TP1 Colorisation de l'Empire Russe
Par Pier-Luc Auger



Explications relatives à l'algorithme 1

Pseudo-code

Au premier numéro, il était demandé de développé un algorithme permettant de recréer une image couleur à partir de trois images ayant été prises avec l'utilisation de trois filtres: rouge, vert et bleu. L'algorithme que j'ai développé est simple et effectue cette tâche tel le pseudo-code ci-bas:

Pour chaque photo:
1.Lire l'image et la convertir
2.Séparer les trois images (B,G,R)
3.Découper les bordures
4.Aligner l'image correspondant au canal G sur B, avec l'approche à une échelle
5.Aligner l'image correspondant au canal R sur B, avec l'approche à une échelle
6.Recomposer l'image avec les trois canaux alignés

À noter que ce pseudo-code sera imagé et détaillé davantage pour l'algorithme 2, qui s'avère très analogue en terme de fonctionnement.

Principe utilisé pour aligner les images

Pour aligner les images, une simple double boucle 'for' parcours une étendue de 15x15 pixels et pour tenter de trouver le décalage optimal pour avoir des images alignées. Pour trouver cet alignement, j'ai procédé en utilisant la somme des différences au carré des deux images. Le résultat optimal est celui retournant la plus basse valeur, car on sait que la somme des différences de deux images et de 0. L'algorithme parcours donc l'étendue et garde en mémoire le meilleur résultat et le retourne lorsque le bouclage est terminé.

Limitation de l'algorithme

Instictivement, on peut apréhender le fait que cet algorithme s'avérera limité dans les contextes où l'image nécessitera d'être décalé au-delà de la plage de 15x15 pixels. Le traitement des images à haute définition m'a rapidement permis de le confirmer. En effet, on remarque que le décalage optimal trouvé par l'algorithme n'est pas exact et on perçoit aisément que l'alignement n'est pas bon. Voici un exemple illustant bien cette limitation. La solution simple que l'on pourrait voir serait de hausser la plage de recherche à par exemple 150x150 pixels. Or là, on se retrouve avec un autre problème: le temps de calcul. En effet, sur un image à haute résolution, le calcul de la SDC devient assez fastidieux, et de le faire 22500 fois pour chacune de nos deux images à aligner devient une opération coûteuse en temps de calcul. C'est pour cette raison qu'un second algorithme a été développé. Nous verons bien qu'un bon design d'algorithme permettra de remplir la même tâche pour des images à haute résolution dans un temps de calcul très court.

Il est à noter que certaines optimisations ont été faites sur ces images, notamment l'ajustement de la balance des blancs, un découpage des bordures de même qu'un ajustement du contraste. C'est optimisations seront détaillées plus bas.

Photos résultantes au traitement par l'algorithme 1

Basses résolutions

00106v.jpg

Décalage du canal rouge : x=9, y=-1
Décalage du canal vert : x=4, y=1

00757v.jpg

Décalage du canal rouge : x=5, y=5
Décalage du canal vert : x=2, y=3

00889v.jpg

Décalage du canal rouge : x=4, y=3
Décalage du canal vert : x=2, y=2

00907v.jpg

Décalage du canal rouge : x=6, y=0
Décalage du canal vert : x=2, y=0

00911v.jpg

Décalage du canal rouge : x=12, y=-1
Décalage du canal vert : x=1, y=-1

01031v.jpg

Décalage du canal rouge : x=4, y=2
Décalage du canal vert : x=1, y=1

01657v.jpg

Décalage du canal rouge : x=11, y=1
Décalage du canal vert : x=5, y=1

01880v.jpg

Décalage du canal rouge : x=12, y=3
Décalage du canal vert : x=6, y=2

Basses résolutions choisies dans la banque

Décalage du canal rouge : x=11, y=2
Décalage du canal vert : x=5, y=2

Décalage du canal rouge : x=11, y=1
Décalage du canal vert : x=5, y=1

Décalage du canal rouge : x=10, y=0
Décalage du canal vert : x=4, y=1

Décalage du canal rouge : x=-1, y=1
Décalage du canal vert : x=-5, y=0

Décalage du canal rouge : x=13, y=-1
Décalage du canal vert : x=5, y=0

Décalage du canal rouge : x=13, y=-1
Décalage du canal vert : x=6, y=0

Décalage du canal rouge : x=11, y=2
Décalage du canal vert : x=5, y=1

Décalage du canal rouge : x=9, y=0
Décalage du canal vert : x=4, y=1

Décalage du canal rouge : x=13, y=7
Décalage du canal vert : x=5, y=4



Explications relatives à l'algorithme 2

Vu le problème rencontré avec les images de haute définition avec l'algorithme 1, il a fallu trouvé un alternative plus perfomante. Les indications dans l'énoncé pointait vers une piste plus qu'intéressante pour y arriver. Cette piste suggérait d'implanter un algorithme récursif travaillant sur des images de résolutions réduite pour trouver le meilleur décalage et d'appeler récursivement l'algorithme de SDC sur les images de résolutions de plus en plus près de la pleine résolution. La méthode que j'ai utilisé va directement en ce sens. J'ai réutilisé mon algorithme de calcul de la SDC auquel j'ai ajouté 2 paramètres correspondant au couple (x,y) qui réfère à un décalage pour démarrer la recherche. Cette astuce m'a permis de découvrir que le décalage trouvé par le SDC n'était jamais plus de 3 pixels à côté du point de recherche que suggérait le calcul du SDC fait sur l'image dont la résolution était 2 fois plus petite. Cela m'a permis d'améliorer la rapidité de calcul en faisant passer la plage de recherche de 15x15 pixels à 5x5 pixels. Un gain appréciable en performance fut perçu.
En amont, le SDC est appelé par un algorithme qui gère la résolution des images passées à la fonction de calcul du SDC. Cet algorithme cherche à construire une pyramide d'images correspondant par exemple à des résolutions de 1/8, 1/4, 1/2 et finalement, pleine résolution. On passe à l'algorithme la 'hauteur' de pyramide qu'on veut, et l'algorithme boucle tant que la pyramide n'atteint pas de hauteur égale à 0. Le facteur de redimensionnement est calculé tel que
resizeFactor=1/(2^pyramidHeight);
lequel nous permet d'utilisé la fonction 'imresize' pour redimensionner nos images avant de calculer d'utiliser le SDC pour trouver le meilleur décalage.
Voici un exemple de trace que laisse mon algorithme. Dans cette trace, on voit bien que la recherche ce fait à la distance double de celle trouvée trouvée par l'itération précédente. C'est logique, car on double la résolution! On remarque aussi ce qui a été énoncé plus haut, à savoir que le décalage n'est jamais bien loin que celui trouvé via l'image de plus basse résolution.

---> New search around offset:(0,0)
---> Best offset:(1,0)

---> New search around offset:(2,0)
---> Best offset:(2,1)

---> New search around offset:(4,2)
---> Best offset:(5,2)

---> New search around offset:(10,4)
---> Best offset:(10,4)

---> New search around offset:(20,8)
---> Best offset:(19,8)

---> New search around offset:(38,16)
---> Best offset:(39,15)

Offset of full definition image is:(39,15)

C'est cet algorithme qui est appelé dans le traitement en boucle effectué sur toutes les images de hautes résolution. Voici en détail l'approche utilisé pour reconstruire l'image couleur. Il faut ici préciser que la logique est la même pour l'algorithme de la question 1, sauf que pour cette question, l'algorithme utilisé pour aligner les trois images est celui détaillé plus tôt.

Limitation de l'algorithme

Ici, le problème rencontré m'a semblé être causé par le calcul du SDC. En effet, il m'est arrivé au départ d'avoir des résultats très mauvais alors que mon algorithme était bien implanté. La cause décelée: un découpage des images R,G,B déficient. En effet, j'ai remarqué que les images hautes définitions sont difficiles à aligner avec le SDC si les bordures sont toujours présentes. En effet, cela est logique puisque ces bordures sont différentes et contiennent des inconsistances qui donnent du fil à retorde à l'algorithme SDC. De fait, l'algorithme pense avoir trouvé un alignement optimal, mais il tenait compte de bordures irrégulières.
Après avoir peaufiner mon algorithme de découpage des images, j'ai aussitôt obtenu d'excellents résultats pour la recomposition d'images couleur.

Pseudo-code imagé de l'algorithme

Pour chaque images:

1.Lire l'image et la convertir (ex: im2double(im1))

2.Séparer les trois images B,G et R (ex: B = im1(1:height,:);)



3.Découper les bordures (avec imcrop())

4.Aligner l'image correspondant au canal G sur B, avec l'approche à échelles multiples (avec l'algorithme développé)

5.Aligner l'image correspondant au canal R sur B, avec l'approche à échelles multiples (avec l'algorithme développé)

6.Recomposer l'image avec les trois canaux alignés (avec cat())

7.Découper les bordures (avec imcrop())


À noter au passage que cet algorithme s'avère tout aussi efficace sur des images de basses résolutions que hautes résolutions.


Optimisations effectuées sur les images (crédits supplémentaires)

Découpage des bordures

Une fonction automatique permet de découper les bordures indésirables. Je n'ai par contre rien développé qui détecte automatiquement les bords.

Avant

Après

Balance des blancs

Il faut noter que certaines images ont été soumises à un équilibrage des blancs avec la méthode Grey World. Entre autre, les photos 00029u.tif, 00737u.tif, 00822u.tif, 00892.tif, 01161u.tif, 01485u.tif.
Les autres images étaient traitées efficacement par l'algorithme, mais le résultat en sortie s'avérait parfoir plus froid et moins intéressant à mon goût personnel. À cet égard, j'admets avoir une préférence pour les photos un peu plus chaudes.

Voici donc 2 exemples d'ajustement de la balance des blancs. Un premier, plus ou moins convaincant et le second, plus intéressant.

Image avant traitement de la balance des blancs

Image après traitement de la balance des blancs

Image avant traitement de la balance des blancs

Image après traitement de la balance des blancs

Ajustement du contraste

Une fonction ajuste le contraste des images. La méthode utilsée procède par équalisation d'histogramme. Les images sont d'abord converties dans l'espace de couleur LAB, ce qui permet de travailler sur le canal de la luminosité. Cela permet ainsi de préserver la couleur originale des pixesls. (Source: Mathworks, Contrast enhancement techniques)

Avant

Après

Photos résultantes au traitement par l'algorithme 2

Hautes résolutions suggérées

00029u.tif

Décalage du rouge : x=91, y =33
Décalage du vert : x=39, y =15

00087u.tif

Décalage du rouge : x=107, y =55
Décalage du vert : x=47, y =38

00128u.tif

Décalage du rouge : x=51, y =38
Décalage du vert : x=35, y =25

00458u.tif

Décalage du rouge : x=87, y =32
Décalage du vert : x=42, y =5

00822u.tif

Décalage du rouge : x=125, y =33
Décalage du vert : x=57, y =25

00892u.tif

Décalage du rouge : x=42, y =4
Décalage du vert : x=16, y =2

01043u.tif

Décalage du rouge : x=11, y =17
Décalage du vert : x=-16, y =10

01047u.tif

Décalage du rouge : x=71, y =33
Décalage du vert : x=24, y =20

00737u.tif

Décalage du rouge : x=49, y =14
Décalage du vert : x=14, y =6

Hautes résolutions choisies dans la banque

01161u.tif

Décalage du canal rouge : x=40, y=18
Décalage du canal vert : x=25, y=-1

01223u.tif

Décalage du canal rouge : x=75, y=2
Décalage du canal vert : x=31, y=10

01234u.tif

Décalage du canal rouge : x=97, y=13
Décalage du canal vert : x=48, y=12

01253u.tif

Décalage du canal rouge : x=121, y=22
Décalage du canal vert : x=54, y=13

01334u.tif

Décalage du canal rouge : x=165, y=16
Décalage du canal vert : x=76, y=16

01406u.tif

Décalage du canal rouge : x=0, y=-9
Décalage du canal vert : x=68, y=31

01485u.tif

Décalage du canal rouge : x=131, y=8
Décalage du canal vert : x=56, y=1

01498u.tif

Décalage du canal rouge : x=118, y=30
Décalage du canal vert : x=52, y=26

Basses résolutions suggérées

00106v.jpg

Décalage du canal rouge : x=9, y=-1
Décalage du canal vert : x=4, y=1

00757v.jpg

Décalage du canal rouge : x=-99, y=64
Décalage du canal vert : x=2, y=3

00888v.jpg

Décalage du canal rouge : x=12, y=0
Décalage du canal vert : x=6, y=1

00889v.jpg

Décalage du canal rouge : x=4, y=3
Décalage du canal vert : x=2, y=2

00907v.jpg

Décalage du canal rouge : x=6, y=0
Décalage du canal vert : x=2, y=0

00911v.jpg

Décalage du canal rouge : x=13, y=-1
Décalage du canal vert : x=1, y=-1

01031v.jpg

Décalage du canal rouge : x=-32, y=1
Décalage du canal vert : x=1, y=1

01657v.jpg

Décalage du canal rouge : x=11, y=1
Décalage du canal vert : x=5, y=1

01880v.jpg

Décalage du canal rouge : x=14, y=4
Décalage du canal vert : x=6, y=2



Photos personnelles traitées par l'algorithme à une échelle

L'utilisation de cette algorithme est plus exigeant en temps CPU. Il faudrait pouvoir agrandir la plage de recherche pour avoir un meilleur résultat. Or, on peut gagner de l'efficacité si on fait le calcul du SDC sur une portion de l'image. On voit bien parmis les résultats ci-bas que le résultat n'est pas toujours aussi bon qu'espéré. Par contre, on verra qu'avec l'algorithme à échelles multiples le résultat est excellent.

(Haute définition)

Décalage du canal rouge : x=11, y=-14
Décalage du canal vert : x=17, y=-14

(Haute définition)

Décalage du canal rouge : x=17, y=-13
Décalage du canal vert : x=9, y=2

(Haute définition)

Décalage du canal rouge : x=17, y=-13
Décalage du canal vert : x=-16, y=22

(Haute définition)

Décalage du canal rouge : x=-5, y=-12
Décalage du canal vert : x=22, y=9

Photos personnelles traitées par l'algorithme à échelles multiples

Dans ces photos, on peut voir que l'algorithme est très efficace pour les images avec un contenu statique. Or, lorsque le sujet est mobile, l'algorithme ne peut pas reconstruire l'image avec réalisme car les 3 images ont été prises à différents moments. C'est d'ailleurs un des problèmes auquel Prokudin-Gorskii a du faire face. Parmis mes images, c'est l'image du feu ardent qui le montre le mieux. En effet, la couleur des flames n'est pas reconstituée avec réalisme.
À l'inverse, sur la photo avec la paire de gants sur l'unité de chauffage, on a même du mal à voir que l'image à été constituée à partir de trois images distintes desquelles ont a extrait respectivement le canal rouge, bleu et vert avant des les alignées pour recomposer l'image finale. À cet effet, on voit plus bas les images correspondant à à chacun des canaux de couleur extrait depuis des images distinctes. Mentionnons au passage que dans ce cas, le modèle rafale utilisé sur l'appareil est intéssant pour prendre les images dans un court laps de temps. L'utilisation d'un trépied serait encore plus intéressant, technique à laquelle Prokudin-Gorskii avait du penser.

(Haute définition)

Décalage du canal rouge : x=20, y=-1
Décalage du canal vert : x=-28, y=3

(Haute définition)

Décalage du canal rouge : x=-1, y=5
Décalage du canal vert : x=1, y=12

(Haute définition)

Décalage du canal rouge : x=8, y=-13
Décalage du canal vert : x=-1, y=-2

(Haute définition)

Décalage du canal rouge : x=10, y=101
Décalage du canal vert : x=-15, y=20

(Haute définition)

Canal rouge extrait de l'image 1

(Haute définition)

Canal vert extrait de l'image 2

(Haute définition)

Canal bleu extrait de l'image 3