Exercices sur les contenus vus durant le CM 8.
Nous continuerons à utiliser Astico2D pour les exercices de TP. Les consignes restent les mêmes :
Nous avons vu en cours que la reconstruction morphologique peut améliorer l'ouverture quand nous cherchons à débruiter un objet discret.
Continuez l'exercice 6 du TP #7 en utilisant la reconstruction morphologique. Faites pour cela une fonction void debruiter(cv::Mat &img_niv, ES &es)
spécialement pour cet objet.
Notez que vous pouvez utiliser différents éléments structurants.
Déclenchez cette fonction avec la touche 1.
Nous commençons maintenant à implanter la transformée en tout-ou-rien.
Définissez un struct appelé TOR_Mask
pour encoder un masque pour une transformée en tout-ou-rien.
Votre structure de données doit être assez flexible pour pouvoir représenter différents masques. Vous avez le choix entre encoder le masque comme une paire d'éléments structurants ou comme une matrice.
Nous pouvons maintenant attaquer l'implantation de l'algorithme d'amincissement.
L'algorithme d'amincissement utilise huits transformées en tout-ou-rien différentes de manière circulaire jusqu'à ce qu'il n'y ait plus de transformations.
Faites une fonction void hit(cv::Mat &img_niv, TOR_Mask &mask)
qui calcule la transformée en tout-ou-rien.
Faites ensuite une fonction void amincissement(cv::Mat &img_niv)
qui calcule l'amincissement d'un objet discret. Notez que, au lieu de déclarer 8 masques, vous pouvez déclarer seulement 2 et faisant une fonction TOR_Mask rotate(TOR_Mask &mask, int turns)
qui fait une rotation de turns
\( \cdot \pi/4 \) radians sur le masque.
Déclenchez l'amincissement avec la touche 2.
Faisons maintenant l'algorithme d'élagage, qui est un peu différent.
L'algorithme d'élagage n'est pas pareil que l'algorithme d'amincissement. Ici nous appliquons tous les masques en même temps comme dans l'algorithme pour calculer l'enveloppe convexe.
Faites une fonction void un_elagage(cv::Mat &img_niv)
qui calcule une itération de l'algorithme d'élagage avec les huit masques (ou deux avec rotations) vus en cours.
Faites ensuite une fonction elagage
qui calcule l'amincissement d'un objet discret et effectue ensuite un nombre d'itérations de l'algorithme d'élagage. Contrôlez le nombre d'itérations avec le slider.
Déclenchez cette fonction avec la touche 3.
Nous implantons ensuite l'algorithme de squelettisation.
Notez qu'on peut associer à chaque pixel du squelette le numéro de l'itération dans laquelle il a été trouvé. Ce sera utile pour la deuxième partie.
Faites une fonction void squelette(cv::Mat &img_niv, ES &es)
qui calcule le squelette d'une image avec un élément structurant.
Déclenchez cette fonction avec la touche 4.
Une propriété remarquable de cet algorithme de squelettisation est qu'il est réversible : on peut reconstruire l'objet initial à partir du squelette. Soit \[ \sigma(A) = \cup_{k \geq 0} \left( \varepsilon_B^k(A) - \varepsilon_B^k(A) \circ B \right) = \cup_{k \geq 0} S_k \] alors \[ A = \cup_{k \geq 0} \delta_B^k(S_k) \]
Faites une fonction void reconstruction(cv::Mat &img_niv, ES &es)
qui calcule le squelette avec la fonction squelette
de l'exercice 5 et reconstruit l'objet initial.
Vous aurez besoin de modifier la fonction squelette
pour sauvegarder la transformée en distance sur le squelette.
Déclenchez cette fonction avec la touche 5.
Affichez l'objet reconstruit et vérifiez qu'il coïncide avec l'objet initial.
Nous implantons ensuite l'algorithme rapide pour calculer la caractéristique d'Euler-Poincaré avec deux masques.
Faites une fonction void euler_local(cv::Mat &img_niv)
qui calcule la caractéristique d'Euler-Poincaré avec la 8-connexité et l'affiche dans la console.
Déclenchez cette fonction avec la touche 6.
Nous allons maintenant vérifier que cette implantation est plus rapide que calculer le nombre de composantes connexes et de trous.
Faites une fonction void euler_global(cv::Mat &img_niv)
qui calcule séparément le nombre de composantes connexes (pour la 8-connexité) et de trous pour obtenir la caractéristique d'Euler-Poincaré et l'affiche dans la console.
Pour cela il suffit de détecter les contours avec la fonction void effectuer_suivi_contours_c8 (cv::Mat &img_niv)
que vous avez fait lors du TP 2 et détecter si le contour correspond à une composante connexe ou un trou à partir de son orientation (voir le CM 2)
Déclenchez cette fonction avec la touche 7.