Slicing et application à la manipulation d'images

Sélection dans les structures de données Python

Les séquences: list, tuple, str, etc

Les slices permettent de sélectionner une sous-séquence dans une séquence (tuple, list, str, etc). Un slice permet d’extraire des données, mais aussi de modifier une structure de données.

l = [n for n in range(10)]
l

Sélection

l[1]
l[1:4]
l[:4]
l[2:7:2]
l[-3:-1]
l[-5:-2:2]
l[::-2]

L’opérateur de slicing [start:end:step] est constitué de trois valeurs.

  1. quelles sont les valeurs de end et step quand seul start est spécifié (ex: l[1])?
  2. quelle est la valeur par défaut de step (ex: l[1:4])?
  3. quelle est la valeur par défaut de start (ex: l[:4])?
  4. À quelle séquence d’indices dans l correspond le slice [2:7:2]?
  5. Que signifient les indices négatifs pour start et end (ex: [-3:-1])?
  6. Que signifie une valeur négative de step (ex: l[::-2])?

Modification

l2 = l[1:4]
l2[1] = 'z'

Quel est l’effet des instructions ci-dessus sur l2? Sur l? Que fait exactement l’opération slice sur une liste?

l[1:3] = ['a', 'b', 'c', 'd']

Quel est l’effet des instructions ci-dessus sur l? Sur l2?

Sélection dans les tableaux numpy

L’opérateur de slicing fonctionne de manière similaire sur les tableaux numpy.

import numpy as np
v = np.array([1,2,3,4,5,6,7])
v[0]
v[3:]
v[2:7:2]
v[-1]

Vérifiez que les slices ci-dessus retournent bien la partie de v attendue.

v[[0, 2, 5]]
v[[0, -1]]
v[[4, -1, 3, 0]]

Que font les instructions ci-dessus?

m = np.array([[1,2,3],[4,5,6]])
m[0][1]
m[0,1]

Bien que les deux dernières expressions retournent la même valeur, la dernière est préférable. Pourquoi?

m[0:2, 0:2]

Pourquoi le slice ci-dessus contient-il deux intervalles 0:2? À quoi correspond chacun d’eux?

m[:, 0:2]

Que signifie le slice :?

Sélection conditionnelle dans les tableaux numpy

m > 2

Quel est le type de la valeur retournée? Que représente-t-elle?

m[m > 2]

Quel est le type de la valeur retournée? Que représente-t-elle?

rows, cols = np.where(m>2)
rows, cols

Que représentent les tableaux rows et cols?

Modification de tableaux numpy

v2 = v[3:]
v2[3] = 12
v2[0:1] = -1

Quel est l’effet des opérations ci-dessus sur v2? Sur v? Que fait l’opération slice sur un tableau numpy (cf. View or shallow copy)

mask = m > 2 
m2 = m.copy()
m2[mask] *= 2

Quelle est la valeur de mask? Quel est l’effet de la dernière instruction sur m2?

m3 = m.copy()
m3[rows, cols] = -1

Que fait l’instruction ci-dessus?

m4 = np.array([[1,2,3,4,5,6], [7,8,9,10,11,12], [13,14,15,16,17,18]])
m4.shape
m4[mask]

Expliquez le message affiché par l’interface en ligne de commande.

m4[rows, cols]

Pourquoi peut-il parfois être intéressant d’utiliser des coordonnées rows, cols plutôt qu’une sélection mask?

Application à la manipulation d’images

Dans cette partie, nous utilisons les modules:

import numpy as np
import matplotlib.pyplot as plt

Prise en main

img = np.random.choice(range(255), (128,128))
img
plt.imshow(img)
plt.show()

Afficher l’image img avec plusieurs codes couleurs différents (cf. liste des codes couleurs).

Une première image

À partir d’un tableau 10x10 rempli de 0, faire un carré de 1 de taille 3x3 à partir de la ligne 2 et colonne 4

Solution
a = np.zeros((10,10))
a[2:5,4:7] = 1

Un échiquier

Écrire les instructions Python qui crée un matrice numpy représentant un échiquier 10x10.

Solution
a = np.zeros((10,10))
a[::2,::2] = 1        # (i,j) en noir si i et j sont pairs
a[1::2,1::2] = 1      # (i,j) en noir si i et j sont impairs

Manipulation de matrices appliquée aux images

curl -fOL https://herbrete.zzz.bordeaux-inp.fr/pg121/kitty.jpg

Que fait la commande ci-dessus? Que signifie les options -f, -O, et -L de la commande curl (cf. man curl)?

img = plt.imread('kitty.jpg')
img.shape

À quoi correspondent les nombres affichés par la commande img.shape (cf. help(numpy.shape))?

img
plt.imshow(img, interpolation='none')
plt.show()

Que signifie le paramètre interpolation='none'?

Réduction de taille

Réduire la taille de l’image par 2, en affichant qu’une ligne sur 2 et qu’une colonne sur 2.

Solution
reduced = img[::2, ::2]
plt.imshow(reduced, interpolation='none')
plt.show()

Niveaux de gris

Afficher l’image en niveaux de gris. Pour cela, passer d’une matrice 3D à une matrice 2D où la valeur de chaque pixel est la moyenne des valeurs RGB. Utiliser l’option cmap='gray' pour l’affichage.

Solution
imgris = img.sum(axis=2) / 3  # on fait la moyenne des r,g,b
plt.imshow(imgris, cmap='gray')
plt.show()

Seuillage (noir et blanc)

À partir de l’image en niveaux gris, créer une image en noir-et-blanc, où les pixels < 125 sont noirs, et les autres blancs.

Solution
imnoir = imgris > 125
plt.imshow(imnoir, cmap='gray')
plt.show()

Rotations

Tourner l’image de 90°, de 180°, puis de 270°.

Solution
img90 = np.rot90(img)
img180 = np.rot90(img, k=2)
img270 = np.rot90(img, k=3)

Chat à 4 yeux

Dans la version en niveau de gris, puis en couleur, faire un chat à 4 yeux en copiant le rectangle englobant ses yeux sur son front.

Solution
yeux = imgris[220:350, 250:700]
imgris[100:230, 200:650] = yeux