Rapport tp4

Dans ce tp, il est demandé de créer une application permetant de créer une mosaïque d'images.

Partie 1: Appariement manuel

Dans cette section, l'utilisateur de l'application précise manuellement des points correspondant dans les deux images. L'application utilise ensuite ces paires de points pour calculer une homographie et faire la transformation d'une image à l'autre.

Pour calculer la transformation, on demande à l'utilisateur d'indiquer un certain nombres de points. On calcule ensuite la matrice de transformation permettant de transformer les points de l'image 1 vers les points de l'image 2. Une fois cette matrice calculée, il faut itérer sur les pixels de l'image résultat, et à l'aide la matrice de transformation inverse, récupérer la valeur des pixels dans l'image source correspondant aux pixels dans l'image résultat.

Les figures suivantes montrent le résultat de l'application sur trois séries d'images fournies par le professeur et sur deux série d'images prisent par moi.

In [1]:
from IPython import display
display.Image(url='images/panorama1/manuel9crop.png', width=750)
Out[1]:
In [2]:
display.Image(url='images/panorama2/13.png', width=750)
Out[2]:
In [3]:
display.Image(url='images/panorama3/08.png', width=750)
Out[3]:
In [4]:
display.Image(url='images/panorama4/03.png', width=750)
Out[4]:
In [5]:
display.Image(url='images/panorama5/03.png', width=750)
Out[5]:

Partie 2: Appariement automatique

Méthode

Si vous avez déjà fait l'exercice, vous remarquerez que prendre plusieurs points correspondant dans la section 1 est plutôt long et pénible. Cette section présente donc une méthode de détection et d'appariement automatique de points.

La détection de coins se fait à l'aide du détecteur de coin Harris. Celui-ci utilise les dérivées en x et en y pour détecter les coins sur une fenêtre. Cette fonction nous retournant une valeur d'intensité du coin pour chaque pixel, il faut faire une fonction pour retrouver les pics dans l'image.

Une fois les pics retrouvées, il faut faire un appariement des points entre eux. Pour ce faire, on extrait des patchs de 8X8 pixels espacées de 5 pixels. Pour avoir une meilleur invariance en translation, j'ai utilisé un opérateur max sur les fenêtres de 5X5 pixels.

Puisqu'il y a un certain nombre de faux positifs dans l'appariement de points, on utilise l'algorithme RANSAC pour trouver la meilleure configuration permettant d'obtenir de bonnes translations.

Résultats

L'appariement automatique marche assez bien pour la première fusion d'images. Par contre, lorsque l'on utilise celui-ci pour plusieurs photos de suite, l'appariement ne fonctionne pas très bien. Je crois que celà est dû au fait que les points extraient par le détecteur de coins ne sont pas assez nombreux et de façon plus importante, pas assez bien distribuées dans l'image. En effet, certaines parties de l'image sont souvent assez peu représentées dans la distribution de points.

La figure suivante montre les points détectés dans chacunes des images.

In [6]:
display.Image(url='images/appariement.png', width=600)
Out[6]:

Les figures suivante montrent les résultats de la fusion de deux images par appariement automatique.

In [7]:
display.Image(url='images/panorama1/auto1.png', width=750)
Out[7]:
In [8]:
display.Image(url='images/panorama2/auto3.png', width=750)
Out[8]:
In [9]:
display.Image(url='images/panorama3/auto2.png', width=750)
Out[9]:
In [10]:
display.Image(url='images/panorama4/auto1.png', width=750)
Out[10]:
In [11]:
display.Image(url='images/panorama5/auto3.png', width=750)
Out[11]:

Pour le cas où l'on tente d'apparier plusieurs photos en même temps, les résultats ne sont pas concluant, comme le montre la photo suivante.

In [12]:
display.Image(url='images/panorama1/testauto1.png', width=750)
Out[12]:

Détection et appariement multi-échelle

Dans la section précédente, le nombre de points trouvés n'est souvent pas assez élevé pour avoir des résultats efficaces. Celà rend la technique difficile à utiliser si on veut apparier plus de deux photos. Une technique permettant d'augmenter de beaucoup la détection de points est de répéter cette opération à plusieurs échelles. Dans la figure suivante, on a utiliser la même technique que précédement, mais en appliquant un redimensionnement précédé d'un filtrage gaussien sur des facteurs 2, 4 et 8. Cela a permit d'augementer le nombre de points détecter. On peut ensuite effectuer un RANSAC sur l'ensemble des points à toutes les échelles.

Par contre, une bonne résolution est importante pour avoir de bons résultats.

In [13]:
display.Image(url='images/automultiscale1.png', width=750)
Out[13]:
In [14]:
display.Image(url='images/automultiscale2.png', width=750)
Out[14]:

Photos historiques

Puisque la 1ère guerre mondiale a 100 ans en ce moment, voici quelques mélanges entre des photos d'époques et des photos modernes.

In [15]:
display.Image(url='images/historique_1918.jpg', width=750)
Out[15]:
In [16]:
display.Image(url='images/historique_2015.jpg', width=750)
Out[16]:
In [17]:
display.Image(url='images/historique.png', width=750)
Out[17]:
In [18]:
display.Image(url='images/historique2_1918.jpg', width=750)
Out[18]:
In [19]:
display.Image(url='images/historique2_2015.jpg', width=750)
Out[19]:
In [20]:
display.Image(url='images/historique2.png', width=750)
Out[20]:

L'ambassadeur de Holbein

Dans cette peinture placé dans un escalier, un crane est représenté pour symboliser la mort. Pusique les gens qui voyaient la peinture montaient un escalier, celui-ci était placé en angle pour apparaître correctement lorsque l'on regardait la peinture d'en dessous.

In [21]:
display.Image(url='images/holbein.png', width=750)
Out[21]:

Étant donné le caractère macabre de la chose, j'ai décider de remplacer le crâne par mon propre visage.

In [22]:
display.Image(url='images/escalier.png', width=750)
Out[22]: