Géométrie Discrète - TP séance 05
- Rendu du TP :
- À la fin de la séance, même si vous ne l'avez pas fini, téléversez votre fichier C++ sur la page Ametice du cours dans la section "Rendu des TPs" en suivant bien les instructions.
- Dans le cas où le TP n'est achevé, il vous est demandé de le terminer chez vous, puis de re-téléverser le fichier lorsqu'il sera dans sa version finale.
1. Transformations de distances pondérées
La série des TP 1 à 4 étant achevée, nous allons débuter un nouveau programme
pour les TP 5 et 6. Recopiez le fichier d'exemple demo1.cpp
sous le nom
tp5-<vos-noms>.cpp
; pensez à inscrire aussi vos noms et la date de la version
à la fin de l'entête.
1.1 Types de base
Déclarer un type enum NumeroMasque
avec les constantes nommées M_D4
,
M_D8
, M_2_3
, M_3_4
, M_5_7_11
, M_LAST
(ce dernier ne symbolise pas
un masque mais sert de marqueur de fin).
Déclarez un type Ponderation
mémorisant les coordonnées x,y
et le poids w
(tous entiers) d'une pondération.
Déclarez un type DemiMasque
mémorisant une liste de pondérations et sa taille
(si besoin), un NumeroMasque
, et le nom
du masque ou de la distance (pour
affichage).
Le constructeur de DemiMasque
prendra en paramètre un NumeroMasque
, puis selon
sa valeur, initialisera le membre nom
à un nom explicite, et peuplera la liste
de pondérations avec les pondérations pour le balayage arrière, c'est-à-dire
telles que (y
> 0) ou (y
== 0 et x
> 0).
Dans la classe MyApp
, mémoriser un numero_masque
et un demi_masque
courants.
Rajouter une bascule avec la touche d
dans handle_keyboard
permettant
de passer de masque en masque, en affichant chaque fois le nom du masque
sélectionné.
(Vous pouvez vous inspirer de l'exemple de la bascule avec la touche n
dans
demo2.cpp
).
1.2 DT Rosenfeld
Écrivez la fonction
calculer_Rosenfeld_DT (cv::Mat &img_int, DemiMasque dm)
qui effectue la transformation de distance séquentielle de Rosenfeld, avec le
demi-masque dm
en paramètre.
Pour le passage avant, utiliser le symétrique du demi-masque (en inversant le signe des coordonnées des pondérations) ; et pour le passage arrière, utiliser le demi-masque tel quel. Attention à ne pas sortir de l'image !
Associer la touche 1
au déclenchement successif de
calculer_Rosenfeld_DT
puis translate_to_vga_colors
.
Vérifiez sur les images de joints que vous obtenez la même chose qu'avec l'algorithme par pelage du TP4 pour les connexités 8 et 4.
1.3 Maximums locaux
Écrivez la fonction
detecter_maximums_locaux (cv::Mat &img_int, DemiMasque dm)
qui reçoit dans img_int
une transformée de distances.
La fonction commence par construire un masque complet formé du demi-masque dm
et du symétrique du demi-masque (en inversant le signe des coordonnées). Elle
réalise ensuite une copie img_dt
de img_int
, puis détecte sur img_dt
les
maximums locaux, de manière à mettre à 0
dans img_int
tous les autres
points. Attention à ne pas sortir de l'image !
- La fonction utilise le critère de maximum local suivant :
- un point \((x,y)\) est maximum local si pour toute pondération \((p_x,p_y,w)\) on a : \(DT[x,y] > DT[x+p_x,y+p_y] - w\)
Associer la touche 2
au déclenchement successif de
calculer_Rosenfeld_DT
puis
detecter_maximums_locaux
et enfin translate_to_vga_colors
.
Vérifiez sur les images de joints que vous obtenez la même chose qu'au TP4 pour \(d_4\) et \(d_8\).
1.4. RDT Rosenfeld
Écrivez la fonction
calculer_Rosenfeld_RDT (cv::Mat &img_int, DemiMasque dm)
qui reçoit dans img_int
une image de maximums locaux.
La fonction effectue la transformation de distance inverse séquentielle de
Rosenfeld, avec le demi-masque dm
en paramètre.
Associer la touche 3
au déclenchement successif de
calculer_Rosenfeld_DT
,
detecter_maximums_locaux
,
calculer_Rosenfeld_RDT
,
et enfin translate_to_vga_colors
.
Vérifiez sur les images de joints que vous retrouvez bien la forme originale , et que vous obtenez la même chose qu'au TP4 pour \(d_4\) et \(d_8\).
1.5 Filtrage des maximum locaux
Rajoutez un slider "Filtre"
avec une valeur maximale de 500
, lié à un
paramètre filtre
stocké dans MyApp
et initialisé à 0
; le slider pourra
être déplacé avec les touches f
et F
.
Écriver la fonction
filtrer_formes_avec_maximums_locaux (cv::Mat &img_int, DemiMasque dm, int filtre)
qui effectue les opérations suivantes :
- appelle
calculer_Rosenfeld_DT
- appelle
detecter_maximums_locaux
- met à 0 tous les maximums locaux \(\leq\)
filtre
- appelle
calculer_Rosenfeld_RDT
sur les maximums locaux filtrés -
enfin, dans le résultat
img_int
, les valeurs des pixels seront mis à- 0 (noir) : points du fond de l'image originale
- 11 (cyan) : points maximums locaux >
filtre
- 8 (gris) : points de la forme obtenue par RDT
- 12 (rouge) : points de la forme originale, non retrouvés par RDT
Associer la touche 4
au déclenchement successif de
filtrer_formes_avec_maximums_locaux
puis translate_to_vga_colors
.
Remarque : le filtre étant très sensible, vous pouvez manipuler le slider avec les touches prévues, par pas de 1.
Taille des lignes de code
Pensez à limiter la taille de vos lignes de code à (environ) 80 caractères, en alignant lorsque nécessaire (par exemple des tests à rallonge) de manière à en faciliter la relecture.