TP3: Morphage de visages

Carl Nadeau 2017

Description du projet

Dans ce troisième travail personnel, nous explorons comment on peut morpher des images entre elle avec des points d'intérêts et de la triangulation.
On effectue plusieurs manipulations matricielles et les temps de calculs deviennent plus grands que dans les derniers travaux.
Avec ce principe, on calcule aussi des visages moyens à partir de base de données d'image.

Partie A : Algorithme de morphage


Dans le code, on retrouve l'algorithme qui permet de morpher des images entre elles.

Nous devions implanter la fonction morphed_img = morph(img1, img2, img1_pts, img2_pts, tri, warp_frac, dissolve_frac) et je l'ai fait dans le fichier morph.m. On utilise très souvent cette fonction dans le reste du TP. La première apparition ce fait dans main.m.
Pour effectuer le calcul, on crée des masques triangulaires définie dans le main et ensuite on transforme les coordonnées en coordonnées homogènes pour effectuer des transformations affines sur trois points en même temps. Ces trois points sont les extrémités de chaque triangle.
Par la suite, je n'utilise pas tsearch et interp2, car j'ai écrites moi-même des opérations équivalentes (possibilités de bonus ;)).

La séquence video en dans le sous fichier video dans la remise du travail avec ça version corrigée. Je vais présenter un GIF ici à la place.

Images demandées
Des images et points de l'image 6 à 7
61 images avec 30 images/secondes (video)
Version avec dlib automatique

On remarque que les points d'intérêts de l'image 7 ne sont pas standard à ce qu'on avait demandé au préalable, ce qui cause un morphage dans des zones d'intérêts non correspondantes.
Pour démontrer que c'est bien l'erreur, j'ai effectué d'autre morphage avec différents individus de la classe.
J'ai produit une version corrigé avec dlib, main_ulaval_67.

Autres morphages
Des images et points de l'image 6 à 2 Des images et points de l'image 6 à 5

Voici 3 animations de morphages avec différents objets.
Ils ont tous 25 points d'intérêts plutôt que 43 comme ceux demandé pour les visages.

Exemple du système à 25 points

Autres morphages
Source : google image Source : google image Incroyable Ado
Source : google image Source : google image Montain Bear
Source : google image Source : google image Gregory Charles Tisseyre

Voici 2 animations de morphages avec mes photos personnelles.
Elles ont tous 25 points d'intérêts plutôt que 43 comme ceux demandé pour les visages.

Source : personnelle Source : personnelle Clash of clans
Source : personnelle Source : personnelle D'Italy en Belgique

Pour les crédits supplémentaires, j'ai implanté un algorithme qui utilise des rectangles au lieu de triangle pour la triangulation. On fait de la "rectangulation".

La fonction morphed_img = morphRect(img1, img2, l_tri_i,l_tri_1,l_tri_2, warp_frac, dissolve_frac) est une version modifiée pour prendre des rectangles et je l'ai fait dans le fichier morphRect.m.
Aussi, la fonction qui différencie tout est [liste_rect,liste_tri,l_tri_1,l_tri_2] = carlRectangle(img1_pts, img2_pts) qui produit les rectangles. En coupe l'image horizontalement et verticalement pour chaque point d'intérêt et cela construit nos triangles.
L'algorithme devient lourd très rapidement avec la quantité de points d'intérêt. On retrouve le main dans main_rectangle.m.

Exemple du système à 5 points avec les rectangles

On retrouve tous les points utilisés dans des fichiers auxiliaires dans le fichier "images".

Partie B1: Calcul du "visage moyen"

Pour cette section, nous devions utiliser le détecteur de point d'intérêt fourni sur le visage de nos camarades de classes et sur les visages d'Utrecth.
Nous avons ensuite modifié le code morph.m pour le rendre en morph_moy.m dans morphed_img = morph_moy(img, img_pts, imgi_pts, tri).
Dans les fichiers main_ulaval_detections et main_utrecht_detections, on retrouve la démarche pour obtenir les visages moyens des différentes bases de données.
C'est vrai aussi pour les autres variantes (femme, homme, souriant, non souriant).

Images demandées
La forme du visage moyen obtenue avec les points que vos camarades étudiants ont sélectionnés Le visage moyen obtenu avec les points que vos camarades étudiants ont sélectionnés
La forme du visage moyen obtenue avec les points trouvés par le détecteur dlib Le visage moyen avec les points trouvés par le détecteur dlib

La forme du visage moyen obtenue avec les points trouvés par le détecteur dlib Le visage moyen obtenu avec les points trouvés par le détecteur dlib

Pour les crédits supplémentaires, j'ai calculé la moyenne des visages souriants et non-souriants en filtrant par nom de fichier. Les fichiers souriants ont un "s" dans leur nom.
Les deux images sont très similaires à l'exception de certains traits et du sourire. Elles sont aussi similaires à la moyenne totale.

Images Bonus

Partie B2: Masculinisation et féminisation de votre visage

Dans cette section, on effectue le même type d'opération avec les filtrages des fichiers par leur nom. Les hommes ont un "m" et les femmes, un "f".
Par la suite, j'ai dû rendre mon "main" main_utrecht_detections_female et main_utrecht_detections_male pour être capable de traiter des images de différentes dimensions.
Après, on joue sur le "warp_factor" et le "dissolve_factor" pour combiner les visages, ici le mien avec la moyenne.

Images demandées
La forme du visage masculin moyen Le visage masculin moyen
La "masculinisation" de votre visage
Warp_factor = 0.2
Dissolve_factor = 0.4
Warp_factor = 0.3
Dissolve_factor = 0.6
Warp_factor = 0.4
Dissolve_factor = 0.8
Warp_factor = 0.5
Dissolve_factor = 0.5
Warp_factor = 0.8
Dissolve_factor = 0.4

Images demandées
La forme du visage féminin moyen Le visage féminin moyen
La "féminisation" de votre visage
Warp_factor = 0.2
Dissolve_factor = 0.4
Warp_factor = 0.3
Dissolve_factor = 0.6
Warp_factor = 0.4
Dissolve_factor = 0.8
Warp_factor = 0.5
Dissolve_factor = 0.5
Warp_factor = 0.8
Dissolve_factor = 0.4
Warp_factor = 0.6
Dissolve_factor = 0.3

Pour les crédits supplémentaires, j'ai produit une animation qui passe de moi qui souris à moi qui ne souris plus. C'est subtil, car la différence entre la moyenne souriante et non souriante l'est aussi.
Mon code est disponible dans le fichier main_smiling. On fait de moyenne pondéré pour effectuer la transition.

Images Bonus
Sourire à non sourire
18 images avec 10 images/secondes

Pour les crédits supplémentaires, je me suis introduit aux notions de PCA pour analyser la répartion des points correspondants entre eux des 131 visages. J'ai aussi modifier mon visage avec le visage le plus moyen de la classe.
Mon code est disponible dans le fichier main_ultrech.apc. On fait la sommes des distances du centre des composantes principales au carré sur tout les 68 points de chaques visages pour trouver avec les extremums les visages le plus normale et le moins normal. Ils sont présenter ci-dessous.

Images Bonus
Visage le plus 'moyen' Visage le moins 'moyen'

Ici le moyennage peut-être causer par le fait que le visage n'est pas centré, contrairement à celui de gauche.

Images Bonus
Mon visage avec le visage le plus moyen de la classe avec les points selectionnés manuellement Mon visage avec le visage le plus moyen de la classe avec les points selectionnés avec dlib

Conclusion

Pour conclure, nous avons réussi à coder un algorithme de morphage en utilisant des transformations affines. Nous avons aussi codé nous mais notre interp2.
Nous avons aussi réussi à calculer les visages moyens d'une base de données et celle des étudiants dans la classe. Nous avons aussi produit de jolies animations.