Vous êtes sur la page 1sur 4

informatique

Corrigé
Traitement d’image

1. Représentation d’une image en Python


Question 1. Pour cette première question, je choisis de créer trois images cides de dimensions identiques à l’image
source, puis à recopier dans chacune des trois l’une des trois composantes couleur de l’image. Ceci conduit au script :

img_rouge = np.zeros_like(img)
img_vert = np.zeros_like(img)
img_bleu = np.zeros_like(img)
n, p = img.shape[:2]
for i in range(n):
for j in range(p):
img_rouge[i, j, 0] = img[i, j, 0]
img_vert[i, j, 1] = img[i, j, 1]
img_bleu[i, j, 2] = img[i, j, 2]

Il reste à les visualiser :


plt.imshow(img_rouge)

plt.imshow(img_vert)

plt.imshow(img_bleu)

Figure 1 – Les trois composantes primaires qui composent l’image test.

Lorsqu’elles sont appliquées à des tableaux de type numpy.array, les fonctions prédéfinies agissent de manière vectorielle ;
ainsi, si t1 et t2 sont deux tableaux de mêmes dimensions, t1 + t2 est le tableau obtenu en additionnant chacune des
cases de mêmes indices (l’addition matricielle, donc). Pour visualiser l’image obtenue en ne gardant que deux des trois
composantes de couleur, il suffit donc d’additionner deux des trois images obtenues ci-dessus :

plt.imshow(img_vert + img_bleu)

plt.imshow(img_bleu + img_rouge)

plt.imshow(img_rouge + img_vert)

Comme cela était prévisible, on obtient des images dont les teintes majoritaires sont les couleurs complémentaires en
synthèse additive des couleurs primaires : le cyan, le magenta et le jaune.
Enfin, la multiplication d’un tableau par un scalaire est aussi une opération vectorielle en Python, ce qui permet de
visualiser simplement une image dans laquelle chaque composante de couleur a été divisée par 2 :

Lycée Marcelin Berthelot page 1


Figure 2 – L’addition de deux des trois composantes primaires.

plt.imshow(img // 2)

Figure 3 – La diminuation de 50% de chacune des trois composantes.

La luminance de chacune des trois composantes de couleur a été diminuée de 50%, ce qui produit une image moins
lumineuse.

Transformations élémentaires
Question 2. Il s’agit ici de remplacer chaque composante de couleur c par sa valeur complémentaire 255 − c. On peut
utiliser l’addition vectorielle pour agir sur les trois composantes de chaque pixel en une fois :
def negatif(im):
n, p = im.shape[:2]
im_neg = np.zeros_like(im)
for i in range(n):
for j in range(p):
im_neg[i, j] = [255, 255, 255] − im[i, j]
return im_neg

Remarque. Bien que cela n’ait aucun sens mathématique, Python permet l’addition d’un scalaire et d’une matrice : dans
ce cas chacune des composantes de la matrice est additionnée avec ce scalaire. Cela permet d’écrire plus simplement la
fonction demandée :
def negatif(im):
return 255 − im

Question 3. Si p désigne le nombre de colonnes de la matrice, le point symétrique du point de coordonnées (i, j) est
celui de coordonnées (i, p − 1 − j). D’où la fonction :
def symetrie(im):
n, p = im.shape[:2]
im_sym = np.zeros_like(im)
for i in range(n):
for j in range(p):
im_sym[i, j] = im[i, p−1−j]
return im_sym

page 2
Question 4. La fonction qui suit tient compte du fait que l’image passée en argument peut ne pas être carrée.

def rotation(im):
n, p, s = im.shape
im_rot = np.zeros((n, p, s), dtype=np.uint8)
for i in range(n):
for j in range(p):
im_rot[p−1−j, i] = im[i, j]
return im_rot

Figure 4 – Le résultat des quatre fonctions demandées sur l’image test.

Conversion en niveau de gris


Question 5. Je choisis de définir tout d’abord une fonction qui calcule la luminance d’un pixel.

def luminance(p):
return np.round(0.2126*p[0] + 0.7152*p[1] + 0.0722*p[2])

Il faut ensuite créer une image bi-dimensionnelle (puisqu’il n’y a plus qu’une seule composante de luminance) et la
remplir :

def niveaudegris(im):
n, p = im.shape[:2]
im_lum = np.zeros((n, p), dtype=np.uint8)
for i in range(n):
for j in range(p):
im_lum[i, j] = luminance(im[i, j])
return im_lum

On visualise le résultat sur l’image test en choisissant la bonne échelle de couleur :

img_lum = niveaudegris(img)
plt.imshow(img_lum, cmap='gray')

2. Traitement d’image
Question 6. Dans un premier temps, je calcule pour chaque pixel le vecteur s dont les composantes sont les valeurs m∗ij
de chacune des trois couches de couleur. Dans un deuxième temps je remplace chaque valeur qui dépasse 255 par 255 et
chaque valeur en deçà de 0 par 0. Enfin, cette valeur est stockée dans la matrice M ⊗ C.
def convolution(m, c):
n, p, q = m.shape
mc = np.zeros_like(m)
for i in range(1, n−1):
for j in range(1, p−1):
s = 0
for u in range(3):

Lycée Marcelin Berthelot page 3


for v in range(3):
s += c[u, v] * m[i−1+u, j−1+v]
for k in range(q):
if s[k] < 0:
mc[i, j, k] = 0
elif s[k] > 255:
mc[i, j, k] = 255
else:
mc[i, j, k] = s[k]
return mc

Question 7.

def lissage(im):
c = 1/9 * np.ones((3, 3), dtype=float)
return convolution(im, c)

def contraste(im):
c = np.array([[0, −1, 0], [−1, 5, −1], [0, −1, 0]], dtype=float)
return convolution(im, c)

def repoussage(im):
c = np.array([[−2, −1, 0], [−1, 1, 1], [0, 1, 2]], dtype=float)
return convolution(im, c)

Figure 5 – Le résultat des trois filtres définis ci-dessus sur l’image test.

3. Stéganographie d’une image


Les fonctions >> et << sont des fonctions vectorielles (comme la plupart des fonctions redéfinies par numpy), ce qui
permet de les appliquer à des tableaux de type numpy.array : dans ce cas, cette même fonction s’applique à chacune des
composantes du tableau. Cette fonctionnalité rend très simples les deux fonctions d’encodage et de décodage :

Question 8.

def encodage(a, b):


return ((a >> 4) << 4) + (b >> 4)

Question 9.

def decodage(c):
return (c << 4)

page 4

Vous aimerez peut-être aussi