Image analogies: transfert de styles entre images


Cadre du projet

Encadrant : Joëlle Thollot, Adrien Bousseau, Pierre Bénard
Etudiants : Rémi Fusade ; Orianne Siret ; Romain Ducout ; Jihene Haboubi ; Hanane Lamrani Abou El Assad

Presentation

Lors de ce projet, nous nous sommes penchés sur la conception d'images par analogie. Le principe de l'analogie est assez intuitif pour nous autres, humains, et permet à partir d'une transformation effectuée sur une image et l'image obtenue, de transformer de la même façon n'importe quelle autre image. Nous avons commencé par étudier l'article de recherche de Aaron Hertzmann, Charles E. Jacobs, Nuria Oliver, Brian Curless et David H. Salesin.

Un algorithme d'analogie était ainsi déjà proposé avec quelques pistes et exemples d'application. Nous avons dès lors implémenté cet algorithme en C++ en essayant d'y apporter diverses optimisations. Puis, nous avons essayé de trouver d'autres applications, laissant dériver notre imagination débordante.

Sur cette page vous trouverez notre cheminement lors de ce projet: Tout d'abord une présentation de l'algorithme qui nous a permis d'obtenir nos résultats. Puis les résultats obtenus classés par domaines d'application. Enfin les problèmes rencontrés et suggestions par rapport à ceux ci. Finalement, les pistes de recherches futures.

Principe de l'algorithme

L'algorithme d'analogie d'images prend en entrée 3 images, une paire d'images sources, A et A', A' étant l'image A filtrée. On souhaite donc calculer une image B' à partir de l'image B tel que l'image B' se rapporte à B de la même manière que A' se rapporte à A.

A chaque pixel d'une image, on associe un vecteur qui liste les informations utilisées par l'algorithme relatives au pixel, cela peut être les composantes RGB, la luminance ou la profondeur. Nous détaillerons plus loin l'utilité des informations et leurs influences sur le résultat. Par la suite, nous noterons A(p), A'(p), B(p) et B'(p) les vecteurs associés aux images, respectivement, A, A', B et B'. Il est important que les images A et A' aient la même taille et que les vecteurs soient identiques pour chaque pixel de chaque image.

Le principe de l'algorithme est simple, on parcourt un à un les pixels de l'image B et on cherche le pixel qui correspond dans l'image A. Le pixel à choisir est celui dont le voisinnage, à la fois dans A et A', est le plus près de celui de B et B'. Afin de capturer les motifs à différentes echelles, on utilise également une pyramide gaussienne et on effectue la recherche à la fois sur les voisinnages au niveau l et au niveau l-1. La synthèse des pixels de B' se faisant du dernier niveau de la pyramide (là où l'image est la plus petite) au premier niveau. Pour calculer la "distance" entre un point q de B et un point p de A, on construit 2 vecteurs, Fa(p) qui réunit les vecteurs des pixels concernés sur l'image A (le voisinage de p dans A, A' aux niveaux l et l-1) et Fb(x) qui réunit ceux de l'image B, on calcule ensuite la distance entre les deux vecteurs.

Le schéma suivant illustre les pixels utilisés lors du calcul de la distance entre les points p et q:
(p étant toujours un pixel de A et q de B)
Afin de trouver le bon pixel, nous utilisons 3 algorithmes différents:
  1. La recherche par force brute: Cet algorithme est utilisé pour la synthèse des pixels en bordure de l'image ainsi que pour la synthèse du dernier niveau de la pyramide de B'. Cette méthode construit le vecteur Fb(q) en fonction des limites de l'image, le voisinage pouvant être trop grand pour des pixels en bordure, et parcourt l'image A sur chaque pixel où le même espace de voisinage existe (c'est pour cela qu'il est utilisé aux bords de l'image). L'algorithme ne travaille pas au niveau infèrieur de la pyramide gaussienne et c'est pour cela qu'il permet de calculer B' au dernier niveau.
  2. L'algorithme de meilleure approximation: Cet algorithme recherche le meilleur pixel de A et A' dans toute l'image où le voisinage de q ne déborde pas de l'image. On utilise ici une bibliothèque nommée ANN (Approximate-nearest-neighbor) qui effectue cette recherche.
  3. L'algorithme de meilleure cohérence: Ce dernier algorithme est utilisé en supplément de l'algorithme de meilleure approximation, il limite la recherche du point de A aux points p correspondants aux voisins de q déjà synthétisés.
Pour chaque pixel q, on choisit le vecteur correspondant au pixel retourné par un des deux derniers algorithmes en fonction d'un paramètre K et de leurs distances au point q, et on l'affecte au pixel q.

Vient alors la dernière étape de l'algorithme qui consiste à construire la valeur RGB des pixels de B' en fonctions du vecteur de pixel. Si le vecteur contient les valeurs RGB, alors il n'y a rien à faire, sinon, par exemple avec la luminance, on recalcule RGB a partir de la valeur de luminance et de la couleur d'un pixel.

Paramètres de l'algorithme

Cet algorithme peut s'adapter aux différentes applications que l'on souhaite en faire, plusieurs paramètres permettent de modifier le comportement de l'algorithme et ainsi d'obtenir des résultats différents. Voici la liste des paramètres de notre algorithme:
  1. K : L'indice de cohérence. Plus il est élevé, plus l'image calculée B' contient d'éléments de l'image A'. Il faut le choisir assez grand (> 0.2) pour tout ce qui concerne la synthèse et le transfert de textures. Mais il doit être le plus petit possible si l'on ne souhaite pas que B' contiennent des "morceaux" de A' (par exemple dans le cas de certains transfert de styles) Figure 3: Exemples de dessin de texture. En prenant comme exemple une photo (A') et une segmentation de texture (A), l'algorithme produit une nouvelle photo texturée (B') dont les formes correspondent à une nouvelle carte de textures (B).

  2. L : Le nombre de niveaux des pyramides gaussiennes. La pyramide gaussienne d'une image est l'ensemble des images réduites (divisées par 2, par 4, par 8, etc...) de l'image originale. L'image de niveau 0 est l'image originale, l'image de niveau l est la réduction par 2 de l'image de niveau l. On les appelle "gaussiennes" car on applique un filtre gaussien pendant la réduction (chaque pixel de la nouvelle image est une combinaison de 9 pixels de l'image précédente). L'algorithme travaille d'abord sur les images de petite taille, puis passe aux images plus grandes. Cette méthode permet de détecter certaines formes qui sont plus grandes que le voisinnage considéré sur l'image originale, et qui deviennent plus petites si on réduit l'image.

  3. pk, gk : Ces paramètres correspondent à la taille du voisinage considéré, respectivement sur les images de taille l+1 et sur les images de taille l. Plus ce voisinage est grand, plus l'algorithme demande du temps à l'exécution, mais il peut détecter de plus grandes formes. L'algorithme tel qu'il est expliqué dans l'article de recherche correspond à pk=1 et gk=2, d'une manière plus générale, on utilisera souvent un rapport de 2 entre ces deux valeurs (même rapport qu'entre les tailles des images), mais nous l'avons généralisé pour n'importe quel autres paramètres (notamment: pk > gk).

  4. type : L'algorithme compare en permanence des pixels à d'autres pixels. Mais il existe plusieurs informations différentes sur chaque pixel, il faut donc choisir laquelle utiliser. Le plus souvent, la luminance (combinaison linéaire des RGB) suffit à donner de bons résultats. Mais parfois, la couleur devient indispensable. Le paramètre "type" offre donc plusieurs possibilités: LUM pour n'utiliser que la luminance, RGB pour n'utiliser que les canaux RGB, RGBLUM pour utiliser les deux, IQ pour n'utiliser que les composantes de couleurs (indépendament de la luminosié), DEPLUM pour utiliser la luminance et une information de profondeur, et enfin DEPRGB pour utiliser les canaux RGB et l'information de profondeur.

  5. Ad, Bd : Lorsque l'on veut rajouter une information sur la profondeur, il est nécessaire de rajouter des images en entrée de l'algorithme. Ad et Bd sont respectivement les cartes de profondeur de A et de B (la profondeur est le niveau de gris de l'image Ad/Bd).

  6. color : Il est possible de générer B' à l'aide des couleurs de B (transfert de style: l'image B' reste semblable à l'image B), ou bien à l'aide des couleurs de A' (synthèse de texture: l'image B' contient des textures de l'image A').

  7. remapping : Dans les cas où les images A et A' sont beaucoup plus claires ou beaucoup plus foncées que l'image B, l'algorithme n'obtiendra rien de bon, il est donc parfois nécessaire de ramener toutes les images à des luminosités semblables. L'option remapping permet d'effectuer ce pré-traitement.

  8. mosaic : Le résultat de notre logiciel est, par défaut, un fichier .tif contenant l'image B'. Mais il est parfois (souvent?) plus pratique de montrer les 4 images A, A', B, et B' dans un même fichier, ne serait-ce que pour les comparer, et vérifier que le résultat est bien celui attendu. L'option mosaic modifie donc ainsi le contenu du fichier de sortie.

Applications

L'algorithme d'analogie d'image fournit de très bons résultats dans des domaines d'application variés. Voici des applications que nous avons testées et qui offrent de bons rendus:
  1. Filtres traditionnels et artistiques.
  2. Synthèse de textures.
  3. Augmentation de la résolution.
  4. Transfert de textures.
  5. Textures par nombres.
  6. Détection de contours.
  7. Profondeur de champ.
  8. Colorisation.
  9. Changements de couleurs.

Limitations

Ouvertures

Téléchargements

  1. Image Analogies. Le code source de notre application
  2. La présentation PowerPoint du projet.

Références

  1. L'article sur lequel nous avons travaillés au cours de ce projet.
  2. Le site web de l'article, vous y trouverez d'autres exemples.