Segmentation et Analyse d`image - TP 2

publicité
Université Bordeaux 1
Master ISV, Image 3D
2013/2014
Segmentation et Analyse d’image - TP 2
Watershed / Ligne de partage des eaux
La ligne de partage des eaux (watershed en anglais) constitue un outil puissant pour analyser
la topographie d’une image. Elle est utilisée en segmentation d’image, puisqu’elle peut délimiter
un ensemble de zones qui forment une partition de l’image originale. Dans ce cadre, la ligne de
partage des eaux est en général appliquée à l’image des contours, où les contours forts peuvent être
vus comme des crêtes qui séparent des vallées assez plates (les régions homogènes). La Figure 1
donne un exemple de segmentation d’image par watershed.
Nous allons mettre en œuvre un algorithme de calcul de la ligne de partage des eaux, proposé
par Vincent et Soille (IEEE PAMI, 1991). Cet algorithme utilise le principe de l’immersion pour
déterminer les bassins d’écoulement. L’algorithme peut se synthétiser ainsi :
1. L’immersion est progressive. A chaque étape, on considère que tous les pixels de niveau < h
ont été traités et on traite le niveau h. On a donc un ensemble de bassins déjà partiellement
repérés, ainsi que certains pixels “frontière” (WATERSHED dans le code) qui séparent deux
bassins distincts.
2. Les pixels de niveau h sont ensuite soit rattachés à un bassin existant, soit repérés comme
étant “frontière”, soit enfin reconnus comme étant un nouveau bassin.
La première étape se réalise assez simplement en triant tous les pixels de l’image suivant leur
valeur. La deuxième étape est plus délicate car elle nécessite de traiter les pixels dans un certain
ordre.
a
c
b
d
Figure 1 – (a) image originale, (b) image de la norme
du gradient calculée par masque de Sobel, (c) ligne de
partage des eaux, (d) minima régionaux (en blanc).
Expérimentation de l’algorithme
L’archive (http ://dept-info.labri.fr/∼vialard/Image3D/src/tp2.tgz) contient :
– un répertoire images contenant des images de test
– un répertoire bin contenant les fichiers .class d’un plugin ImageJ de calcul de watershed.
– un répertoire src contenant les fichiers source du plugin à compléter.
Testez le plugin avec les paramètres suivants :
Image
laBaule_spot
laBaule_spot
tools
tools
tools
Entrée de l’algorithme
gradient
gradient
gradient
gradient
gradient
5
25
5
20
40
Refaites les mêmes tests sur les images préalablement traitées par un filtre moyenne puis par
un filtre médian.
Que constatez-vous ? A quoi sert en pratique le paramètre epsilon, qui permet de considérer
des pixels d’altitude proche comme ayant la même altitude ? Est-ce que l’algorithme est sensible
au bruit de l’image ?
Calcul de la ligne de partage des eaux
Les entrées de l’algorithme sont :
– une image de nombre flottants (les altitudes des pixels)
– un nombre flottant (incertitude sur l’altitude)
En sortie, l’algorithme fournit une image d’entiers : chaque pixel contient soit une étiquette
correspondant à un bassin, soit WATERSHED s’il sépare deux bassins.
Editez la classe Watershed et sa méthode calculeWatershed. Observez bien ce qui est déjà
écrit (voir aussi la Figure 2). Les étapes de l’algorithme, déjà écrites ou à compléter, sont les
suivantes :
1. Les pixels sont d’abord triés par ordre croissant d’altitude.
2. Ils sont ensuite traités par série : tous ceux entre h et h+ sont considérés d’altitude identique.
3. Ces pixels sont alors MASKés et il faut déterminer à quel bassin ils appartiennent.
4. On commence par traiter les nouveaux pixels MASKés qui touchent déjà un bassin (pixel
étiqueté) ou une frontière (pixel WATERSHED). Ils sont à distance 1. Les autres MASKés
seront à distance 2, 3, voire plus. Voir (II) dans le code Watershed.java.
5. Ces pixels sont placés dans une file d’attente. Un élément fictif indique la fin de file et donc
le passage à des pixels à des distances supérieures. Voir (III) dans le code.
6. Etant donné un pixel dans la file, on peut maintenant le traiter en fonction de son voisinage.
Implémentez l’étiquetage du pixel courant. Voir (IV.TODO). Pour ce faire, reprenez les cas
possibles (cf. Figure 3). Les points suivants sont importants :
– On ne teste que les voisins de distance inférieure à la distance courante (les autres, de
même distance que le pixel courant, sont traités en parallèle).
– Le calcul se fait en regardant successivement les quatre pixels adjacents : le pixel courant
peut donc être réétiqueté différemment plusieurs fois.
– Le pixel sera étiqueté soit par un label voisin, soit par WATERSHED.
– Il faut aussi déterminer les pixels voisins à distance +1 et les mettre dans la file. A la
détection, ils sont de distance nulle et MASKés.
7. La dernière phase de l’algorithme reprend tous les pixels traités, et s’ils ne sont pas étiquetés,
leur donne une nouvelle étiquette. Tous les voisins non étiquetés sont étiquetés de même par
propagation. Implémentez cet étiquetage des nouveaux bassins. Voir (V. TODO).
Reprenez les tests du premier exercice.
Fermeture des frontières entre bassins
La ligne de partage des eaux telle que calculée par cet algorithme ne crée pas des frontières
complètes autour des régions. En effet, les frontières sont placées sur les pixels à égale distance
entre deux bassins. Complétez la méthode fermeWatershed pour fermer les frontières après calcul
du watershed.
2
UNLABELLED
11
00
00
11
00
11
0
1
2
2
1
2
1
2
MASK (distance)
1
2
WATERSHED
1
111
000
000
111
000
111
000
111
000
111
2
Label0
1
Label1
1
Label2
000
111
11
00
000
111
00
11
00
11
00
11
00
11
00
11
00
11
00
11
00
11
Figure 2 – Illustration d’une étape de l’algorithme. Pour chaque pixel MASKé, les flèches indiquent les seuls voisins pris en compte dans la détermination de son label. (a) légende des
étiquettes. (b) traitement des pixels MASKés à distance 1 du bord, (c) traitement des pixels
MASKés à distance 2 du bord, (d) fin de l’itération.
avant
après
Impossible
11
00
00
11
000
111
000
111
000
111
11
00
00
11
11
00
00
11
00
11
111
000
00
11
000
111
00
11
00011
111
0011
11
00
11
00
11
00
00
00
00 11
11
00 11
0011
11
0000
11
00
11
00
11
000
00
11
00 111
11
000
111
00
11
00 111
11
000
00
11
Figure 3 – Illustration de l’étiquetage d’un pixel MASKé. La nouvelle étiquette dépend des
étiquettes des voisins. Un certain nombre de configurations sont illustrées.
Le principe est simple : pour chaque pixel p de l’image, s’il y a un pixel voisin dont le label est
inférieur, alors p doit être étiqueté comme “frontière”.
Est-ce que cette technique de fermeture est indépendante d’une rotation ou symétrie de l’image ?
Affichage des bassins selon la moyenne
Proposez une autre façon d’afficher les bassins, non plus avec une couleur aléatoire, mais avec
le niveau de gris moyen de la région correspondante dans l’image originale. Voyez-vous un intérêt
autre que juste visuel à cette transformation ?
Pour aller plus loin...
L’algorithme produisant souvent beaucoup de petites régions peu significatives, écrivez une
méthode de Watershed qui agrège les petites régions aux régions voisines, en privilégiant la ligne
de partage des eaux la plus basse.
La façon la plus simple de procéder est de reprendre l’algorithme de calculeWatershed et de
le modifier ainsi :
– Il faut un tableau d’indirection de labels qui permet de réétiqueter les labels existants.
– Il faut mémoriser au fur et à mesure la taille de chaque région.
– Lorsque deux régions se touchent, on a un comportement différent si une des deux régions
est d’une taille inférieure à un seuil donné en paramètre. Dans ce cas-là, on indique que les
deux bassins sont identiques en mettant à jour le tableau d’indirection de labels.
Une autre méthode pour limiter le nombre de petites régions est la simplification par marquage.
Elle est très similaire à la méthode précédente, sauf que c’est l’utilisateur qui marque des pixels
correspondant à des bassins. Les bassins qui ne contiennent pas de marque s’absorbent les uns les
autres. Si un bassin contient une marque, il absorbe les bassins qui n’en ont pas. Si deux bassins
qui contiennent chacun une marque se touchent, alors dans ce cas-là seulement, on construit la
ligne de partage des eaux entre les deux.
3
Téléchargement