TP2: Découpage d'images

- Redimensionnement par «sculptage» -

par Olivier Duguay

GIF-4105/7105 Photographie Algorithmique, Hiver 2015

1-Objectifs du projet 2-Approche et méthode choisie 3-Résultats 4-Les (+) 5-Les (-)

1-Objectifs du projet

Dans le cadre de ce deuxième projet du cours de photographie algorithmique, il nous faut implémenter une fonction qui permet le redimensionnement dynamique d'image. En fait, il faut faire en sorte de réduire la taille d'une image soit à l'horizontal ou à la vertical et ce en faisant en sorte de conservé le plus fidèlement possible, l'image originale. Par fidèle, on entend le fait d'avoir une image qui ressemble en tout point à l'image d'origine et qui conserve le plus possible les points d'intérêts de la photo, en engendrant le moins possible d'aléa et de déformation dans l'image.

Pour plus de détails, voyez l'énoncé complet ICI.

2-Approche et méthode choisie

Afin de faire le découpage dynamique d'une image, il faut d'abord avoir une référence sur ce qui est intéressant dans une image (exemple, le portrait d'une personne) versus ce qu'il l'est moins tel qu'un fond (background) trop prolongé ou simplement des zones sans détails importants. Cette référence est une fonction d'énergie de l'image qui détermine les pixels les plus importants de ceux qui le sont moins.

Un bon choix de fonction d'énergie est de travailler avec les gradients provenant de l'image en niveaux de gris. De cette façon, on ne prends nullement en compte les différences couleurs, mais seulement les changements d'intensité. Il est possible d'utiliser le gradient de magnitude et directionnel provenant la fonction Matlab appelé IMGRADIENT, et d'additionner ceux-ci pour obtenir la fonction d'énergie de l'image, cependant il est préférable d'utiliser la fonction IMGRADIENTXY qui retourne les gradients de direction dans la direction de X et Y. De cette façon, on trouve les pixels où la variation est la plus grande pour une direction donnée (horizontale ou verticale / x ou y) ce qui indique une arête prononcée et donc, une plus grande possibilité d'avoir un objet important de l'image à cette endroit.

L'image suivante montre les fonctions d'énergie de l'image en X, en Y et les 2 fonctions additionnées (en valeurs absolues) qui forment la fonction d'énergie de l'image que nous utiliserons pour notre algorithme.

Gradient en X

Gradient en Y

Gradient X+Y (fonction d'énergie)

Comme on le remarque bien avec cette image de dessins pixelisés, il est facile de bien déterminer les variations / arêtes en X et Y si bien, qu'une fois les gradients additionnés, on obtient presqu'une image en noir et blanc avec toutes les arêtes en blancs. Tous les personnages sont facilement identifiable et on sait ainsi que notre algorithme devrait bien fonctionner pour ce type d'image.

Ensuite, une fois la fonction d'énergie déterminée, il faut également choisir quels joints (en anglais, «seams») sont les plus importants et lesquels le sont moins car on ne peut pas simplement enlever le pixel avec le moins d'importance car on créerait des «trous» dans l'image de même que de simplement enlever une ligne ou colonne comportant l'énergie la plus faible, car on engendrait de graves déformations sous formes de zig-zag dans l'image. Il nous a donc fallu créer un algorithme de détection dynamique des joints de faibles importances assez robuste pour conserver de façon efficace la qualité de l'image et sa représentation.

En bref, l'algorithme parcours tous les pixels de la première ligne (ou colonne) à la recherche de la plus faible énergie, en vérifiant les pixels avoisinants (+/- 1 pixel de proximité) de la seconde ligne (ou colonne) pour qu'elle possède aussi la plus faible énergie, et ainsi de suite, on met à jour ces valeurs jusqu'à ce qu'on ait parcouru toute la hauteur (ou largeur) de l'image. Il faut boucler ainsi pour tout les chemins optimaux. En bouclant à l'inverse, on retrouve les coordonnées de tous ces pixels de faibles énergies que l'on met dans un vecteur qu'on soustrait de l'image originale pour ainsi recommencer jusqu'à ce que l'on ait le redimensionnement désiré. Pour redimensionner dans la direction opposée, il suffit d'utiliser la transposée de l'image dans l'algorithme. Il ne faut pas oublier d'enlever le joint dans les trois canaux de l'image (RGB). Finalement, après optimisation, on se rend compte qu'il est mieux de mettre un cadrage avec une forte valeur d'énergie puisque l'algorithme à tendance à choisir souvent les bordures.

L'image animée suivante nous montre comment l'algorithme fonctionne brièvement. On y voit les joints être mis en ROUGE avant d'être retirés de l'image originale.

Pour des images de plus de 1000 pixels de large ou de haut, il est nécessaire de tout d'abord réduire l'image d'un certain facteur afin d'effectuer les calculs sur une image plus petite (plus petite matrice = moins de calculs). Puis, une fois l'algorithme terminée, on augmente l'image du facteur inverse de celui utilisé pour le rapetissement de l'image pour ainsi obtenir un résultat de redimensionnement dynamique qui est à l'échelle de l'image d'origine. Tel est le cas pour les images que j'ai pris moi-même dans la prochaine section. Il faut noter que ceci entraîne une certaine erreur qui se transpose sur l'image sous la forme de flou.

3-Résultats

Les résultats obtenus sont présentés à cette section et sont classés selon les directives. Il est important de noter que tous les images ont été redimensionnées d'un facteur de 30%

Images prédéterminées par le professeur

House - Image Originale
Dimension : 512 x 384 pixels

House - Image découpée VERTICALEMENT
Dimension : 358 x 384 pixels

House - Image découpée HORIZONTALEMENT
Dimension : 512 x 269 pixels

Tower - Image Originale
Dimension : 640 x 434 pixels

Tower - Image découpée VERTICALEMENT
Dimension : 448 x 434 pixels

Tower - Image découpée HORIZONTALEMENT
Dimension : 640 x 304 pixels

F* Yo Couch - Image Originale
Dimension : 375 x 500 pixels

F* Yo Couch - Image découpée VERTICALEMENT
Dimension : 262 x 500 pixels

F* Yo Couch - Image découpée HORIZONTALEMENT
Dimension : 375 x 350 pixels

Street Corner - Image Originale
Dimension : 648 x 432 pixels

Street Corner - Image découpée VERTICALEMENT
Dimension : 454 x 432 pixels

Street Corner - Image découpée HORIZONTALEMENT
Dimension : 348 x 302 pixels


Images provenant "des" Internet

Stade Olympique - Image Originale
Dimension : 762 x 507 pixels
Source

Stade Olympique - Image découpée VERTICALEMENT
Dimension : 533 x 507 pixels

Stade Olympique - Image découpée HORIZONTALEMENT
Dimension : 762 x 355 pixels

Muhammad Ali vs. Sonny Liston - Image Originale
Dimension : 712 x 630 pixels
Source

Muhammad Ali vs. Sonny Liston - Image découpée VERTICALEMENT
Dimension : 498 x 630 pixels

Muhammad Ali vs. Sonny Liston - Image découpée HORIZONTALEMENT
Dimension : 712 x 441 pixels

Meilleurs amis - Image Originale
Dimension : 880 x 586 pixels
Source

Meilleurs amis - Image découpée VERTICALEMENT
Dimension : 616 x 586 pixels

Meilleurs amis - Image découpée HORIZONTALEMENT
Dimension : 880 x 410 pixels

Nintendo - Image Originale
Dimension : 1920 x 1200 pixels
Source

Nintendo - Image découpée VERTICALEMENT
Dimension : 1344 x 1200 pixels

Nintendo - Image découpée HORIZONTALEMENT
Dimension : 1920 x 840 pixels


Mes images

Canyon Mont Ste-Anne - Image Originale
Dimension : 1936 x 2592 pixels

Canyon Mont Ste-Anne - Image découpée VERTICALEMENT
Dimension : 1356 x 2592 pixels

Canyon Mont Ste-Anne - Image découpée HORIZONTALEMENT
Dimension : 1936 x 1816 pixels

Mariage - Image Originale
Dimension : 1936 x 2592 pixels

Mariage - Image découpée VERTICALEMENT
Dimension : 1356 x 2592 pixels

Mariage - Image découpée HORIZONTALEMENT
Dimension : 1936 x 1816 pixels

Château Frontenac - Image Originale
Dimension : 1936 x 2592 pixels

Château Frontenac - Image découpée VERTICALEMENT
Dimension : 1356 x 2592 pixels

Château Frontenac - Image découpée HORIZONTALEMENT
Dimension : 1936 x 1816 pixels

Zoé - Image Originale
Dimension : 3264 x 2448 pixels
Source

Zoé - Image découpée VERTICALEMENT
Dimension : 2284 x 2448 pixels

Zoé - Image découpée HORIZONTALEMENT
Dimension : 3264 x 1712 pixels

Les (+)

On remarque que pour des images où les objets sont clairement bien définis du décor ou simplement des paysages avec des textures très opaques comme c'est le cas pour les images du hibou et du chien, le Canyon, le Château, la maison ainsi que les photos découpées horizontalement de mon chien Zoé et le le Stade Olympique. Malgré quelques petites distorsions et artéfacts au niveau du décor comme par exemple l'aliasing en bordure du stade et l'effet de vague de la route avoisinante ainsi que les oreilles coupées du chien avec le hibou, les images sont sommes toute, treès bien redimensionnées et représentent efficacement l'image d'origine.

Pour des images avec des arêtes très bien prononcées, l'algorithme fait également bien l'affaire comme on le remarque pour les photos de la tour, du graffiti et celle de l'image à l'effigie de Nintendo. On peut ainsi affirmer que les traits très droits, et bien distincts les uns des autres permettent de bien redimensionner les images.

Les (-)

Cependant, l'algorithme à ses limites. En effet, pour des images très détaillées comme il est le cas de l'image du coin de rue, il est difficile de déterminer un joint optimal puisque toute l'image paraît intéressante en se basant uniquement sur une fonction d'énergie car tous les détails font en sorte que chaque joint possède sensiblement la même énergie.

Il en ait de même pour l'image prise lors d'un mariage où les personnes (mon ami le marié et moi-même) se confondent avec le décors déjà assez fournies en détails. Ceci à pour effet que l'algorithme coupe au travers des personnes ou à leurs tout juste limites. Cette effet ce remarque aussi pour la photo de boxe coupée horizontalement alors que Muhammad Ali semble se retrouver avec la chevelure de Elvis Presley et un bras à moitié mangé.

Pour éviter ce phénomène, une fonction par sélection de zone d'intérêt qui ajoute à une région désignée (ROI, region of interest), une très forte intensité d'énergie a été entamée mais n'a pu être peaufinée à temps. De plus, une fonction aurait pu être codé de façon à choisir automatique ce qui doit être retirer entre un joint horizontal et un joint vertical pour effectuer le redimensionnement puisque malgré tous, il y aura toujours une limite avant laquelle l'image sera nécessairement déformée si les échelles entre l'image d'origine et celle modifiée diffèrent beaucoup.