Exercices Computer Vision Opérations morphologiques : erosion et dilatation
🎉

Bravo!

Avancé 🧠 Fondamentaux 30 XP 0 personnes ont réussi

Opérations morphologiques : erosion et dilatation

En inspection industrielle, après avoir seuillé une image pour détecter des défauts sur une pièce, tu te retrouves souvent avec du bruit : des petits points blancs parasites, des trous dans les zones détectées, des objets qui se touchent alors qu'ils sont séparés. Les opérations morphologiques sont les outils de nettoyage qui règlent tous ces problèmes. On les utilise aussi en OCR pour séparer les lettres collées, en analyse cellulaire pour compter des cellules au microscope, et en cartographie pour simplifier les contours des zones géographiques.

Imagine que tu sculptes un bloc d'argile. L'érosion, c'est comme passer du papier de verre : les petites excroissances disparaissent, les bords s'affinent, les objets rétrécissent. La dilatation, c'est comme ajouter une couche d'argile : les trous se bouchent, les objets grossissent, les formes proches se rejoignent.

En pratique, tu utiliserais cv2.erode(image, kernel) et cv2.dilate(image, kernel), ou encore cv2.morphologyEx() pour des opérations combinées comme l'ouverture (érosion puis dilatation) et la fermeture (dilatation puis érosion). Ici on implémente érosion et dilatation avec NumPy pour bien comprendre la logique.

L'érosion réduit les zones blanches. Chaque pixel blanc ne reste blanc que si TOUS ses voisins (dans le kernel) sont aussi blancs. Sinon, il devient noir. Effet : les petits points blancs isolés disparaissent, les objets rétrécissent.

La dilatation agrandit les zones blanches. Chaque pixel noir devient blanc si AU MOINS UN de ses voisins est blanc. Effet : les trous dans les objets sont comblés, les objets grossissent.

L'élément structurant (kernel) définit le voisinage. Un kernel 3x3 de uns est le plus courant.

Écris deux fonctions qui travaillent sur des images binaires (valeurs 0 ou 255, dtype uint8) :

eroder(image_binaire, taille_kernel) qui applique une érosion avec un kernel carré de taille donnée. Renvoie l'image érodée.

dilater(image_binaire, taille_kernel) qui applique une dilatation avec un kernel carré de taille donnée. Renvoie l'image dilatée.

Les bords non traitables sont laissés à 0.

Exemple :
Un petit point blanc isolé (1 pixel) disparaît après érosion.
Un petit trou noir (1 pixel) dans une zone blanche disparaît après dilatation.

Ce que tu devrais voir sur ta machine : après un seuillage, applique une érosion puis une dilatation (on appelle ça une ouverture morphologique) pour nettoyer le bruit.

Tests (5/5)

Erosion supprime point isole
import numpy as np
img = np.zeros((7, 7), dtype=np.uint8)
img[3, 3] = 255
result = eroder(img, 3)
assert result[3, 3] == 0, 'Un pixel isole doit disparaitre apres erosion'
Erosion conserve zone pleine
import numpy as np
img = np.full((7, 7), 255, dtype=np.uint8)
result = eroder(img, 3)
assert result[3, 3] == 255, 'Le centre d une zone pleine doit rester blanc'
Dilatation agrandit
import numpy as np
img = np.zeros((7, 7), dtype=np.uint8)
img[3, 3] = 255
result = dilater(img, 3)
assert result[3, 3] == 255, 'Le pixel central doit rester blanc'
assert result[2, 3] == 255, 'Les voisins doivent devenir blancs'
assert result[3, 4] == 255, 'Les voisins doivent devenir blancs'
Dilatation comble un trou
import numpy as np
img = np.full((7, 7), 255, dtype=np.uint8)
img[3, 3] = 0
result = dilater(img, 3)
assert result[3, 3] == 255, 'Un trou noir isole doit etre comble par la dilatation'
Dtype conserve
import numpy as np
img = np.zeros((5, 5), dtype=np.uint8)
result_e = eroder(img, 3)
result_d = dilater(img, 3)
assert result_e.dtype == np.uint8
assert result_d.dtype == np.uint8

Indices (3 disponibles)

solution.py