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.