TP1 - Colorisation de l'empire Russe

De Camille Leverrier

Description

L'objectif de ce TP est de créer des images couleurs avec trois photographies en noir et blanc pour chaque image, obtenu avec un filtre rouge, vert et bleu. Pour la réalisation de ce TP, j'ai procédé de manière itérative, en modifiant mon programme au fur et à mesure de mon avancement pour l'amélioration de mes résultats. J'ai commencé avec l'analyse de la somme des carrés pour l'approche à une seule échelle mais le résultat n'était pas parfait alors j'ai décider d'ajouter un filtre sur l'image pour améliorer la précision lors de mes recherches de translations. Je me suis aperçue également qu'il n'était pas nécessaire d'étudier l'image entière alors j'ai choisi de prendre qu'un pixel sur deux. Par la suite, pour l'approche à échelles multiples, j'ai commencé en divisant l'image de 1/8 pour gagner en rapidité.

1- Approche à une seule échelle

Pour la première partie, approche à une seule échelle, j'ai débuté en appliquant la norme L2, qui consiste à faire la somme des différences au carré de la valeur des pixels entre deux images. Pour trouver la transformation necessaire entre deux images, j'applique une translation allant de [-15,15] suivant l'axe des x et suivant l'axe des y, sur l'une des deux images. J'en déduis par la suite, la translation qui engendre une somme des différences au carré la plus petite. Les translations obtenues pour chaque image sont annotées en dessous de celles-ci. Le premier vecteur représente le déplacement de l'image correspondant au filtre vert par rapport au bleu, et le ddeuxième celui du rouge par rapport au bleu.
Pour rendre le programme plus rapide, j'ai choisi de ne pas appliquer la somme des différences au carré à tous les pixels mais seulement tous les 5 pixels. De plus, je n'ai pas pris en compte les pixels proches des bordures afin d'éviter des erreurs dans la recherches des translations à cause de celles-ci. Pour augmenter la précision lors du calcul, j'ai décidé d'appliquer avant celui-ci, un filtre accentuant les détails des images (EDGE_ENHANCE_MORE).
code python : TP1_1-q1
Pour commencer, les images sont extraites de l'image originale comme ci-dessous.
Rouge Vert Bleu
Par la suite, le filtre EDGE_ENHANCE_MORE leur est appliqué.
Rouge Vert Bleu
00106v (-1,-4) (1,-9)
00757v (-3,-2) (-5,-5)
00888v (-1,-6) (0,-12)
00889v (-2,-2) (1,-5)
00907v (-1,-1) (1,-6)
00911v (1,-1) (1,-13)
01031v (-1,-1) (-2,-4)
01657v (-1,-6) (-1,-12)
01880v (-2,-6) (-4,-14)

2- Approche à échelles multiples

Pour la deuxième partie, approche à échelles multiples, je me suis basée en grande partie sur l'algorithme précédant. Pour les images données, cela nécessitait au préalable, de les convertir puiqu'elles étaient en 16 bits, contrairement aux autres en 8 bits.
J'ai commencé par redimensionner les trois images, après les avoir découpées de l'image initial, en 1/8 de leur taille initiale afin d'y rechercher les transformations entre [-20, 20]. Une fois la première translation connue, je l'applique à l'image redimensionnée en 1/4 de la taille de l'image initiale. Puisque la taille de cette image est deux fois celle en 1/8, il ne faut pas oublier de multiplier les translations par deux. Je peux par la suite rechercher les translations entre [-2, 2]. J'effectue la même chose pour l'image en 1/2 de la taille réelle et l'image en taille réelle et je peut trouver ainsi plus rapidement les translations. La translation finale est donc 8*translation en 1/8 +4*translation en 1/4 +2*translation en 1/2 + translation en 1.
code python : TP1_1-q2
  • Image 1/8 : (-2,-5) (-5,-11)
  • Image 1/4 : (-1,-0) (2,-1)
  • Image 1/2 : (2,0) (1,0)
  • Image 1 : (2,0) (0,1)
  • Image 1/8 : (-5,-6) (-7,-14)
  • Image 1/4 : (1,0) (0,2)
  • Image 1/2 : (-1,1) (1,-1)
  • Image 1 : (1,1) (-1,0)
  • Image 1/8 : (-3,-4) (-5,-6)
  • Image 1/4 : (0,-1) (1,-1)
  • Image 1/2 : (1,2) (0,1)
  • Image 1 : (2,-1) (1,0)
  • Image 1/8 : (-1,-6) (-4,-10)
  • Image 1/4 : (0,2) (0,-3)
  • Image 1/2 : (0,0) (1,-1)
  • Image 1 : (2,0) (2,-2)
  • Image 1/8 : (-1,-2) (-2,-6)
  • Image 1/4 : (0,0) (0,0)
  • Image 1/2 : (0,0) (1,-1)
  • Image 1 : (0,1) (0,-1)
  • Image 1/8 : (-3,-7) (-4,-15)
  • Image 1/4 : (0,-1) (0,-1)
  • Image 1/2 : (0,2) (1,0)
  • Image 1 : (2,-1) (2,-2)
  • Image 1/8 : (0,-1) (-1,-4)
  • Image 1/4 : (0,-2) (1,-2)
  • Image 1/2 : (0,0) (0,-1)
  • Image 1 : (1,1) (2,2)
  • Image 1/8 : (-1,-2) (-2,-1)
  • Image 1/4 : (0,1) (0,-1)
  • Image 1/2 : (-2,-1) (1,0)
  • Image 1 : (2,-1) (0,-1)
  • Image 1/8 : (-3,-3) (-4,-8)
  • Image 1/4 : (1,0) (0,-1)
  • Image 1/2 : (0,0) (0,-2)
  • Image 1 : (1,-1) (-1,1)
  • Image 1/8 : (-2,-3) (-5,-10)
  • Image 1/4 : (0,1) (0,0)
  • Image 1/2 : (0,-1) (0,1)
  • Image 1 : (1,2) (2,-1)
  • Image 1/8 : (-2,-5) (-2,-11)
  • Image 1/4 : (2,-1) (0,-2)
  • Image 1/2 : (0,0) (1,-1)
  • Image 1 : (-1,-1) (1,0)
  • Image 1/8 : (-2,-2) (-4,-10)
  • Image 1/4 : (0,-1) (0,-1)
  • Image 1/2 : (0,0) (1,-1)
  • Image 1 : (1,0) (2,-1)
  • Image 1/8 : (-2,-6) (-1,-15)
  • Image 1/4 : (0,-1) (-1,-1)
  • Image 1/2 : (1,0) (0,1)
  • Image 1 : (1,2) (2,-2)
  • Image 1/8 : (-4,-7) (-8,-15)
  • Image 1/4 : (0,1) (1,0)
  • Image 1/2 : (1,-1) (0,-2)
  • Image 1 : (0,-1) (0,-1)
  • Image 1/8 : (-2,-6) (-4,-14)
  • Image 1/4 : (-1,-1) (-1,0)
  • Image 1/2 : (1,1) (1,1)
  • Image 1 : (0,2) (0,1)
  • Image 1/8 : (2,-5) (4,-11)
  • Image 1/4 : (0,0) (-1,-1)
  • Image 1/2 : (1,0) (0,0)
  • Image 1 : (-1,0) (0,-1)
  • Image 1/8 : (-3,-5) (-5,-16)
  • Image 1/4 : (1,1) (-1,1)
  • Image 1/2 : (0,0) (2,-1)
  • Image 1 : (0,-1) (2,-2)
  • Image 1/8 : (0,-5) (0,-12)
  • Image 1/4 : (0,-1) (0,0)
  • Image 1/2 : (-1,2) (0,-2)
  • Image 1 : (2,0) (1,-2)
  • Image 1/8 : (-1,3) (-1,0)
  • Image 1/4 : (1,-2) (0,-2)
  • Image 1/2 : (0,0) (-1,-1)
  • Image 1 : (-1,-1) (0,-2)

3- Dans la peau de Prokudin-Gorskii

Pour cette partie, j'ai utilisé des photographies personnelles. Pour la première, j'ai séparé une photographie en noir et blanc en trois images représentant le rouge, le vert et le bleu. Par la suite, j'ai appliqué une translation aux images représentant le vert et le rouge.
code python : TP1_1-q3
  • Image 1/8 : (0,-2) (-1,1)
  • Image 1/4 : (1,-3) (-3,1)
  • Image 1/2 : (1,-2) (-2,1)
  • Image 1 : (1,-2) (-2,2)
Pour la deuxième image, j'ai choisi trois photographies différentes sue lesquelles j'ai récupéré les canaux rouge, vert et bleu. On peut voir que le résultat n'est pas parfait en partie à cause du déplacement entre les images mais aussi des personnes qui se sont déplacée d'une photographie à l'autre.
  • Image 1/8 : (-3,-1) (0,2)
  • Image 1/4 : (-3,-2) (-2,3)
  • Image 1/2 : (-2,0) (-2,0)
  • Image 1 : (-2,-1) (-2,2)
  • Image 1/8 : (7,0) (-3,0)
  • Image 1/4 : (5,1) (-5,1)
  • Image 1/2 : (1,-1) (-2,2)
  • Image 1 : (2,-2) (-2,1)
Pour la dernière image, on observe que les translations trouvées correspondent bien pour le paysage au loin mais pas pour les arbres du premier plan. Le déplacement, même faible, est beaucoup plus visible proche de l'objectif ce qui donne un mauvais rendu pour l'image finale.

Bonus

Pour améliorer la qualité de l'image, j'ai choisi d'analyser l'histogramme de l'image pour trouver la valeur moyenne de celui-ci. Par la suite, j'augmente le contraste tout en recentrant la moyenne. On peut voir ci-dessous l'histogramme correspondant à l'image et le résultat de celle-ci après amélioration.
code python : Histogramme
Pour la detection des bordures, je me suis basée sur le fait que les bordues ne sont pas identiques selon les images/canaux. Je fais le calcul de la somme des différences au carré en fonction de la découpe des bordures. La plus petite somme indique donc le bon découpage des bordures. Malheureusement, j'ai remarqué que cela fonctionne moins bien lorsque par exemple la selection se fait avec un ciel bleu ou de l'herbe verte. Dans ces cas, l'algorithme aurait des difficultés à différencier les bordures du reste de l'image. Dans le cas de l'image suivante, la décupe de l'image pour la bordure trouvée est de (15, 18).
code python : Bordure
Pour réduire les imperfections des images, j'ai observé les différences entre un pixel et son prédecesseur. Si une forte différence est détectée sur un seul des canaux, je lui donne alors la valeur moyenne des pixels l'entourant (carré de 30*30). Malheureusement, j'ai remarqué que cela engendre en même temps une perte de détail sur l'image.
code python : Correction
Pour contrer le problème du déplacement lors de la prise des photographies, nous pourrions utiliser un descripteur tel que ORB pour faire correspondre les images et avoir une transformation plus précise. Avec ORB, on trouve des points d'intérêts dans les images qu'on peut alors comparer pour trouver la différence de leur position et ainsi et déduire la transformation.

Ont trouve ici une transformation entre ces images de (1,-13)