Python pour le calcul scientifique/Traitement d'images

Rappelons que dorénavant les programmes commencent tous par :

#!/usr/bin/python3

import numpy as np
import matplotlib.pyplot as plt

Charger et enregistrer une image

modifier

La manipulation des fichiers d'image peut se faire avec la bibliothèque imageio[1] (image input/output, entrées et sorties d'images). La lecture d'un fichier se fait avec la fonction imageio.imread(), qui transforme l'image en une matrice NumPy[2]. L'écriture d'une matrice sous la forme d'un fichier d'image se fait avec la fonction imageio.imwrite().

L'affichage de la matrice sous forme d'image se fait avec la fonction plt.imshow().

Par exemple, téléchargeons l'image Husky puzzle book au format 320 × 240 (« 320px-Husky_puzzle_book.svg.png ») et mettons là dans le répertoire de travail. Puis :

import numpy as np
import matplotlib.pyplot as plt
import imageio as iio

image = iio.imread("320px-Husky_puzzle_book.svg.png") # chargement de l'image
plt.imshow(image) # affichage de l'image
iio.imwrite("320px-Husky_puzzle_book.svg.bmp", image) # enregistrement au format bitmap

print(type(image)) # <class 'imageio.core.util.Array'>
print(image.shape) # (240, 320, 4)

Vous remarquerez que l'image originelle a une partie transparente (canal alpha) et que cela se transforme en noir dans l'image au format .bmp.

Nous pouvons également utiliser la bibliothèque PIL (Python imaging library, bibliothèque d'imagerie Python)[3], et en particulier sa section Image. Elle contient la fonction PIL.Image.open() qui permet de charger le fichier dans un objet d'une classe spécifique. Cette classe propose des méthodes dédiées comme .show() pour montrer l'image et .save() pour l'enregistrer.

On peut transformer cet objet en matrice NumPy avec la commande numpy.asarray(). À l'inverse, on peut transformer une matrice NumPy en image PIL avec la commande PIL.Image.fromarray().

Par exemple :

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

image = Image.open("Husky_puzzle_book.svg.png") # chargement de l'image
plt.imshow(image) # affichage de l'image
image.show() # autre méthode d'affichage de l'image
image.save("Husky_puzzle_book.svg.bmp") # enregistrement au format BMP

matriceImage = np.asarray(image)

print(type(image)) # <class 'PIL.PngImagePlugin.PngImageFile'>
print(type(matriceImage)) # <class 'numpy.ndarray'>
print(matriceImage.shape) # (240, 320, 4)

image2 = Image.fromarray(matriceImage)
print(type(image2)) # <class 'PIL.Image.Image'>
image2.save("foo.gif")

Le module matplotlib dispose d'un bibliothèque image[4].

Format des matrices

modifier

Les matrices images sont en fait des tenseurs d'ordre 3.

Si l'image est composée de L × l pixels, avec 16 millions de couleurs[5], et qu'il n'y a pas de canal alpha (pas de transparence), la matrice image est une matrice de dimension (L, l) dont chaque cellule est un vecteur de dimension 3. La cellule [i – 1, j – 1] contient la couleur du pixel (i, j) au format [R, V, B], chaque composante étant un nombre compris entre 0 et 255.

Par exemple :

A = np.array([[[0, 0, 0], [255, 0, 0]],
             [[0, 255, 0], [0, 0, 255]]])
plt.imshow(A)

S'il y a un canal alpha, alors chaque vecteur est de dimension 4. La cellule [i – 1, j – 1] contient la couleur du pixel (i, j) au format [R, V, B, A], la valeur A étant l'opacité cotée de 0 (totalement transparent) à 255 (totalement opaque). Par exemple :

plt.clf()

B = np.array([[[255, 0, 0, 0], [255, 0, 0, 85]],
             [[255, 0, 0, 170], [255, 0, 0, 255]]])
plt.imshow(B)

Si le vecteur représentant un pixel n'a qu'une dimension (c'est donc un scalaire), alors la valeur est convertie en couleur selon la matrice de couleurs en cours (colormap). Pour avoir un rendu en niveaux de gris, il faut utiliser la fonction matplotlib.pyplot.gray(). Par exemple :

plt.clf()

C = np.array([[[0], [85]],
             [[170], [255]]])
plt.gray()
plt.imshow(C)

Fonctions spécifiques

modifier

Notes et références

modifier
  1. (en) « Imageio » (consulté le 28 juin 2022).
  2. Les fonctions scipy.misc.imread() et scipy.misc.imsave() sont obsolètes et ont été retirées en 2018.
  3. Par exemple dans sa version (en) « pillow » (consulté le 28 juin 2022).
  4. « matplotlib.image », sur Matplotlib.org (consulté le 14 avril 2023).
  5. Ou plus exactement 224 = 16 777 216 couleurs.

Calcul symbolique < >