Aller au contenu

Géométrie Discrète - TP séance 04

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. Remplissage de l'approximation polygonale

Recopiez votre programme du TP3 en le renommant tp4-<vos-noms>.cpp ; pensez à inscrire aussi vos noms et la date de la version à la fin de l'entête.

a) Modifiez le type ContourF8 et la fonction suivre_un_contour_c8 de manière à ce qu'elle mémorise dans le résultat ContourF8, en plus des informations actuelles, la direction initiale (vers le fond) reçue en paramètre.

b) Écrivez une fonction remplir_polyg qui prend en entrée le résultat ContourPol de approximer_contour_c8, ainsi qu'une image de int, et une couleur de remplissage coul (un entier). Elle colorie ensuite avec la couleur coul dans l'image tous les pixels à l'intérieur du polygone en appelant la fonction cv::fillPoly.

(Pour un exemple d'appel, voir https://stackoverflow.com/a/8283145 ; le paramètre pour mettre à la couleur coul est cv::Scalar(coul)).

c) Écrivez une fonction approximer_et_remplir_contours_c8 qui prend en entrée la liste des ContoursF8 produite par effectuer_suivi_contours_c8, un seuil réel, ainsi qu'une image de int ; elle vide l'image (avec la méthode setTo), puis pour chaque ContourF8, elle approxime le contour avec approximer_contour_c8, puis remplit chaque polygone dans l'image avec remplir_polyg.

Pour "recréer" les trous dans l'image il devrait suffire de choisir comme couleur de remplissage 255 si c'est un contour externe, sinon 0 (contour de trou). Comme les contours de trous sont détectés après les contours externes, l'ordre de remplissage des contours devrait permettre de récréer formes et trous originaux (à l'approximation près).

On utilisera l'heuristique suivante : les contours externes ont une direction de Freeman initiale vers le haut (6) ou à gauche (4), tandis que les contours de trous l'ont vers le bas (2) ou à droite (0).

d) Associer la touche 6 au déclenchement de effectuer_suivi_contours_c8 suivi de approximer_et_remplir_contours_c8, avec le seuil du slider "Polyg" divisé par 100.0, et enfin translate_to_vga_colors. Observez l'évolution des formes et des trous lorsque le seuil varie.

2. Transformations de distances par pelage

Dans les questions suivantes, attention à ne pas sortir de l'image pour les tests de voisinage !

a) Écrivez une fonction effectuer_pelage_DT (cv::Mat &img_int, int connexite), où connexite est 4 ou 8 ; la fonction initialise les points objet (> 0) à INT_MAX (défini dans <climits>), puis effectue le pelage contour par contour de tous les objets présents dans l'image, avec la connexité duale (puisqu'on teste des voisins du fond).

b) Associer la touche 7 au déclenchement successif de effectuer_suivi_contours_c8, approximer_et_remplir_contours_c8, effectuer_pelage_DT , et enfin translate_to_vga_colors.

La connexité courante sera mémorisée comme membre de la classe MyApp, et pourra être changée au clavier en tapant sur la touche c ; elle sera affichée dans le terminal à chaque changement.

c) Écrivez une fonction detecter_maximums_locaux (cv::Mat &img_int, int connexite) qui prend en entrée l'image résultat de effectuer_pelage_DT, puis la recopie dans une image tmp avec la méthode clone. Elle met ensuite à 0 tous les points de img_int qui sont > 0 et non maximums locaux dans tmp pour la connexité duale.

d) Associer la touche 8 au déclenchement successif de effectuer_suivi_contours_c8, approximer_et_remplir_contours_c8, effectuer_pelage_DT, detecter_maximums_locaux, et enfin translate_to_vga_colors.

Observez l'évolution des maximums locaux lorsque vous modifiez le seuil de polygonalisation ; comparez l'aspect en fonction de la connexité.

e) Écrivez une fonction effectuer_pelage_RDT (cv::Mat &img_int, int connexite) qui effectue la transformation de distance inverse par pelage, à partir des maximums locaux contenus dans img_int, pour la connexité duale.

Conseil : commencer par chercher la valeur maximale m dans img_int, puis procéder par niveau k depuis m-1 jusqu'à 1 ; pour chaque niveau k, marquer à k les points < k qui ont au moins un voisin > k pour la connexité duale.

f) Associer la touche 9 au déclenchement successif de effectuer_suivi_contours_c8, approximer_et_remplir_contours_c8, effectuer_pelage_DT, detecter_maximums_locaux, effectuer_pelage_RDT, et enfin translate_to_vga_colors.

Vérifiez sur les images de joints que vous retrouvez bien les formes approximées lorsque vous modifiez le seuil de polygonalisation.

3. Finition

Mettez à jour print_keyboard_keys par exemple ainsi :

        // Indiquez ici les touches du clavier et vos transformations
        std::cout <<
            "  1     contours pour c8\n"
            "  2     contours pour c4\n"
            "  3     numerotation contours pour c8\n"
            "  4     suivi de contours pour c8\n"
            "  pP    change le seuil de polygonalisation\n"
            "  5     approximation polygonale + coloriage\n"
            "  6     approximation polygonale + remplissage\n"
            "  c     change la connexite pour les traitements suivants :\n"
            "  7       DT par pelage\n"
            "  8       maximums locaux\n"
            "  9       RDT par pelage\n"
        << std::endl;

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.