Aller au contenu

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.