Aller au contenu

Chp K : Traitement de l'image avec numpy et matplotlib

Ă€ noter : l'objectif indirect de ce chapitre est la manipulation de tableaux 2D, soit par double boucle, soit directement via numpy et les slices.

I. Une image numérique c'est quoi ?!

Faisons un bref récapitulatif des informations dont on a besoin pour notre propos.

En informatique, une image peut être définie de plusieurs façons. L'une d'entre elle consiste à découper l’image en une multitude de points élémentaires, appelés pixels (en anglais pour picture element), comme si l’on posait une grille (on dit une matrice) géante (souvent plusieurs millions de cases !) sur l’image. On parle d'image bitmap, ou encore d'image matricielle. Ces cases sont appelées des pixels. On s'intéresse à la couleur de chacun de ces pixels. Pour une image en niveaux de gris (à différencier d'une image en noir & blanc !), un choix usuel est que chaque case de la matrice contient un nombre entier compris entre 0 et 255, qui correspond au niveau de gris souhaité (0 pour noir, 255 pour blanc). Si l'image est en couleur, en général chaque case contient un triplet de valeurs elles aussi entre 0 et 255 (correspondant aux composantes Rouges, Vertes et Bleues). On se contentera cette année afin d'alléger un peu nos algorithmes, de ne traiter que des images en niveaux de gris (donc une seule composante). Les pixels sont suffisamment petits pour ne pas être visibles à l’oeil nu. Exemple: un smartphone qui prend des photos à «12 mégapixels» va découper l’image suivant une grille de 4000 colonnes et 3000 lignes, soit 12 millions de cases!

zoom_bitmap.png

Avantages et inconvénients

  • Avantages : PossibilitĂ© de reprĂ©senter très fidèlement n’importe quelle image (si on prend assez de pixels et de couleurs!)
  • InconvĂ©nients :
    • La taille du fichier est souvent très importante.
    • Perte de qualitĂ© importante au changement d’échelle (si on double la taille, on double la taille des cases qui peuvent Ă©ventuellement devenir visibles, mĂŞme si en rĂ©alitĂ© on peut faire mieux avec le rĂ©-Ă©chantillonnage...)

On se rend compte qu'au final, travailler sur une image de type bitmap, revient à travailler sur un (très) grand tableau 2D.

II. Mise en place de l'espace de travail

1. Import des modules

Pour récupérer, traiter et afficher une image, on va ici utiliser les modules matplotlib et numpy.

# les bibliothèques que l'on va utiliser

import matplotlib.pyplot as plt
import matplotlib.image as iplt
import numpy as np

2. Chargement de l'image en mémoire

Pour charger l'image dans un tableau 2D, c'est la commande imread du module iplt:

color_datas = iplt.imread('nom_de_image.jpg') 
On peut voir le type et les dimensions de l'image

print("type :",type(color_datas))
print("shape :",np.shape(color_datas))
print("pixel (0,0) :",color_datas[0,0])
type : <class 'numpy.ndarray'>
shape : (262, 420, 3)
pixel (0,0) : [ 67 128   0] # on remarque bien le triplet pour le pixel (0,0)

3. Conversion en niveau de gris

Pour éviter de travailler sur les trois composantes, on va convertir cette image en niveaux de gris

On fait une moyenne coefficientée des trois composantes sur chacun des pixels.

# conversion en niveau de gris
conversion = [0.2989, 0.5870, 0.1140] # coefficients pour la moyenne
datas = np.dot(color_datas,conversion) # chaque pixel est multiplié par conversion
datas = datas.astype(np.int32) # on convertit les types (flottants) en entiers

print("type :",type(datas))
print("shape :", datas.shape)
print("datas[0,0] = ",datas[0,0])
type : <class 'numpy.ndarray'>
shape : (262, 420)
datas[0,0] =  95
# constater le "shape" de la variable 'datas' qui est maintenant un tableau 2D

4. Affichage

Pour afficher un tableau 2D sous forme d'image :

1
2
3
4
5
6
7
8
9
def display(tab, fig = 1):
    """ reçoit un tableau 2D d'entiers compris entre 0 et 255,
    et affiche l'image correspondante """
    plt.figure(fig)
    plt.clf()
    plt.imshow(tab,cmap='gray',vmin=0,vmax=255) # on crée en mémoire la figure (comme d'habitude ave plt.plot)
    plt.show() # on affiche la figure à l'écran.

display(datas,1)

Explications rapides (on utilisera cette fonction en TD):

  • ligne 4 : on donne un numĂ©ro Ă  la figure de sorte que dans le notebook, les figures des diffĂ©rentes questions ne se mĂ©langent pas.
  • ligne 5 : on efface le contenu de la figure (utile si on l'a dĂ©jĂ  utilisĂ©e avant)
  • ligne 6 : on utilise la fonction imshow pour afficher le tableau 2D tab en niveaux de gris (paramètre cmap='gray'), avec des valeurs allant de 0 Ă  255 (paramètres vmin et vmax)
  • ligne 7 : on affiche la figure Ă  l'Ă©cran.

III. Les TDs

On va maintenant passer Ă  la pratique en envisageant en TD toute sorte de manipulation d'image.

TD K1 : manipulations diverses sur une image (sur un tableau 2D)

TD K1 version interactive capytale

Versions html : Énoncé et Correction (à venir)

TD K2 : Stéganographie (message crypté par une image)

TD K2 version interactive capytale

Versions html : Énoncé et Correction (à venir)