Maîtrise d'informatique - Module 11
|
Lors de la première séance de TP, vous avez effectué les phases de calibrage et d'appariement (en utilisant les contraintes épipolaire, d'unicité et de seuillage) sur une paire d'images de synthèse de taille 128x128. Dans cette deuxième séance de TP, vous allez programmer la phase de triangulation (phase 3), qui a été vue à la fin du chapitre 3. Vous produirez ainsi un fichier contenant les altitudes Z des points de la scène, et vous visualiserez ce relief à l'aide de Khoros. Enfin, s'il vous reste un peu de temps, le paragraphe 5 vous propose de programmer un algorithme permettant d'appliquer la contrainte d'ordre lors de la phase d'appariement, chose qui n'avait pas été faite lors de la première séance de TP. Cela permettra de diminuer le nombre de faux appariements.
Lorsque vous serez parvenu à réaliser un programme répondant exactement aux questions de la première séance de TP, faites-en une copie. C'est à partir de cette copie que vous allez travailler dorénavant. Vous allez programmer la phase 3 de l'algorithme de stéréovision qui a été vu en cours (phase de triangulation). Écrivez la fonction d'en-tête :
void triangulation(float Z[N][N],short Cg[N][N])
qui calcule l'altitude pour les pixels appariés de l'image gauche, et la stocke dans le tableau Z. Ce tableau recevra la valeur 0.0 pour les pixels non appariés.
Dans la version actuelle de Khoros disponible sur les machines Silicon Graphics, vous n'avez pas accès à la visualisation en perspective d'un relief 3D. Le seul moyen de pallier à ce défaut est de convertir le tableau Z en un tableau de niveaux de gris I (valeurs comprises entre 0 et 255), et de stocker les valeurs de ce tableau dans un fichier qu'on visualisera ensuite sous forme d'image. Les niveaux de gris de cette image représenteront en fait des altitudes (on parle de "faux niveaux de gris"), suivant une relation linéaire telle que :
Remarquez que cette transformation serait impossible si toutes les valeurs de l'altitude étaient égales (ce qui n'est pas le cas ici).
1- Déclarez le tableau unsigned char I[N][N] qui contiendra les niveaux de gris décrits ci-dessus.
2- Écrivez la fonction d'en-tête :
void conversion(float Z[N][N],unsigned char I[N][N])
qui permet d'affecter aux cases du tableau I les valeurs décrites ci-dessus.
3- Écrivez la fonction d'en-tête :
void ecrire(unsigned char I[N][N])
qui permet de stocker les valeurs du tableau I dans un fichier au format "brut", de nom relief.brt
4- Modifiez le programme principal, de façon à effectuer la phase de triangulation, et à écrire le fichier relief.brt. Les constantes T et S gardent les valeurs respectives 1 et 0.01
5- Visualisez le fichier relief.brt, en tant qu'image, à l'aide de Khoros.
Parvenez-vous à interpréter le relief correspondant à cette image en "faux niveaux de gris" ?
Si oui, êtes-vous convaincu, sur cet exemple, que la vision par ordinateur peut être plus performante que la vision humaine ?
La contrainte d'ordre a été vue au paragraphe 3 du chapitre 3. Si deux paires de pixels (Igi,j1, Idi,l1) et (Igi,j2, Idi,l2) situées sur la même ligne ne vérifient pas l'inégalité suivante :
(j2-j1)(l2-l1) >= 0
alors on dit qu'on a à faire à une inversion. Pour éliminer toutes les inversions, il va falloir nécessairement supprimer un certain nombre de paires de pixels. On a bien sûr tout intérêt à en supprimer le moins possible. On peut imaginer un grand nombre d'algorithmes permettant de forcer cette contrainte. Nous vous proposons l'algorithme suivant :
1- On cherche s'il reste des inversions.
2- S'il reste au moins une inversion, on cherche les paires de pixels qui sont impliquées dans le plus grand nombre d'inversions.
3- On retire toutes ces paires de pixels, puis on retourne à l'étape 1.
Vous allez programmer cet algorithme dans le paragraphe suivant.
On introduit le tableau short inv[N][N], pour lequel la case inv[i][j] est censée contenir :
1- Écrivez la fonction d'en-tête :
short inversions(short inv[N][N],short Cg[N][N])
qui remplit le tableau inv[N][N], et qui retourne la valeur maximale contenue dans ce tableau.
2- Écrivez la fonction d'en-tête :
int ordre(short inv[N][N],short Cg[N][N])
qui applique l'algorithme décrit dans le paragraphe précédent, en appellant la fonction inversions, et qui retourne le nombre de paires qui ont dû être retirées pour que la contrainte d'ordre soit vérifiée.
3- Modifiez le programme principal de manière à ne plus appliquer la contrainte de seuil, à appliquer la contrainte d'ordre et à faire afficher le nombre de paires retirées.
1- Testez le programme précédent (qui n'utilise plus la contrainte de seuil) avec la constante T égale à 1. Vous devez obtenir l'affichage suivant :
Nombre de paires retirées par la contrainte d'ordre : 106
Pourcentage de paires restantes : 89.13 %
2- Lorsque la constante T est égale à 2, vous devez obtenir l'affichage suivant :
Nombre de paires retirées par la contrainte d'ordre : 43
Pourcentage de paires restantes : 88.12 %
3- Si vous appliquez la contrainte de seuil avant la contrainte d'ordre, avec T=1 et S=0.01, vous devez avoir :
Nombre de paires retirées par la contrainte d'ordre : 0
Pourcentage de paires restantes : 86.72 %
Quelle conclusion pouvez-vous tirer de ce dernier résultat ?