Post-traitement d’images binaires à l’aide d’opérations morphologiques#

Les opérations morphologiques transforment les images en fonction de leur forme ; généralement, nous parlons d’images binaires dans ce contexte.

import numpy as np
from skimage.io import imread
import matplotlib.pyplot as plt
from skimage import morphology
from skimage import filters

Noyaux, empreintes et éléments structurants#

Si nous travaillons avec scikit-image, de nombreux filtres morphologiques ont un paramètre footprint. Cette empreinte est le noyau du filtre, et dans la littérature, vous trouverez également le terme élément structurant pour cela.

# crée un disque de 1 avec un rayon = 3
disk = morphology.disk(3) 
disk
array([[0, 0, 0, 1, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 0],
       [0, 0, 0, 1, 0, 0, 0]], dtype=uint8)
plt.imshow(disk, cmap='gray')
<matplotlib.image.AxesImage at 0x225b0c88340>
../_images/2ce56700144d6f8989abd8050950954b7bd4789e6cd2a1099608849e30beabe7.png
# crée un carré avec une largeur et une hauteur = 3
square = morphology.square(3) 
square
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]], dtype=uint8)

Morphologie binaire#

Pour démontrer le filtrage morphologique des images binaires, nous utilisons à nouveau la petite image de noyaux.

image_nuclei = imread('../../data/mitosis_mod.tif').astype(float)
image_binary = image_nuclei > filters.threshold_otsu(image_nuclei)

plt.imshow(image_binary, cmap='gray')
<matplotlib.image.AxesImage at 0x225b0d05490>
../_images/56ab869e45d7333845132a88738966b807dd35f12510c333bbe203c03660b693.png

Érosion et Dilatation#

Pour réduire les îles blanches dans l’océan noir, nous devons éroder leurs côtes.

eroded = morphology.binary_erosion(image_binary, disk)

plt.imshow(eroded, cmap='gray')
<matplotlib.image.AxesImage at 0x225b0d80dc0>
../_images/d838c1304d54d3eaa1ff7f21cf123079d931e4f7dccf866c0345ea5f62330954.png

Si nous dilatons l’image par la suite, nous obtenons des îles blanches qui semblent plus lisses que dans l’image binaire originale.

eroded_dilated = morphology.binary_dilation(eroded, disk)

plt.imshow(eroded_dilated, cmap='gray')
<matplotlib.image.AxesImage at 0x225b107f730>
../_images/7c55ef4ae2d61ff4f6963cd2545398174849e8f30a917c3925d3720cdfa4693b.png

L’application successive de l’érosion et de la dilatation est si courante qu’il existe une fonction spéciale qui fait exactement cela. Comme l’écart entre les îles ouvre, l’opération est appelée ouverture.

opened = morphology.binary_opening(image_binary, disk)

plt.imshow(opened, cmap='gray')
<matplotlib.image.AxesImage at 0x225b10f9b20>
../_images/7c55ef4ae2d61ff4f6963cd2545398174849e8f30a917c3925d3720cdfa4693b.png

Exercice 1#

Il existe également une opération de fermeture. Appliquez-la à l’image binaire.

Exercice 2#

Recherchez dans la documentation de scikit-image les filtres minimum et maximum. Appliquez le filtre minimum à l’image binaire, puis le filtre maximum au résultat. Comparez-le aux images montrées ci-dessus.