Projet Final: Mosaicage d'images dynamique

Description :

Le projet que j'ai choisi consiste à faire générer une image avec un object en movement à partir d'un vidéo. Plus précisément, l'algorithme doit prendre les images d'un vidéo et garder un nombre d'images choisi par l'utilisateur étalé sur tout le video. Ensuite, il faut extraire l'object en mouvement de chaque image choisie et toutes les placer sur une même image. Dans les fait, on voit souvent ce genre d'image dans des photos de sports. J'ai choisi d'implanter mon algoritme sur des photos de ski. Voici un exemple d'image d'un résultat trouvé sur internet.

https://m1.behance.net/rendition/modules/39798027/disp/e9154b1ffc4aac5f4568c72c71632134.jpg

Algorithme retenu

J'ai débuté en orientant mon algorithme en fonction des couleurs avec un algorithme de "graph cut", mais ce travail est très lent puisque qu'il faut que je parcours plusieurs fois tous les pixels. j'ai remarqué que mes vidéos sont très stable, alors j'ai ensuite orienté mon algorithme sur le mouvement de l'objet.

Selection d'images

Le nombre de vues sur l'object en mouvement est choisi par l'utilisateur au début. il faut extraire dans un premier temps la première et la dernière photo du vidéo. Ensuite, on prend le reste des photos avec un intervalle constant pour avoir un bon essemble de photos. Pour une photo avec quatre fois l'objet en mouvement, voici les images retenues.

Création d'une image vide

La seule intervention humaine se fait ici. Il faut que l'utilisateur encadre avec la fonction "roipoly" de Matlab l'object sur la première photo. Avec ces informations on remplace le contenu de ce masque par le contenu de la dernière image pour créer une image vide. Il y a bien sur l'ombrage qui est différente, mais cela ne cause pas de problème. Voici le masque selectionné de la première image et l'image vide.

Création d'un masque de l'object en mouvement

Pour chaque image, il est possible de trouver l'object en mouvement en comparant les pixels des 3 canaux sur une image et l'image vide. Pour se faire on calcul la somme des différences aux carrées entre tous les canaux et sur tout les pixels de l'image. Ensuite on utilise une valeur limite pour trouver si c'est un pixel en mouvement ou non. Une valeur de threshold qui fonctionne bien pour tous les vidéos est de 0,14. Une masque est finalement trouver avec ce calcul.

Pour améliorer le masque, je supprime tous les objects à l'intérieur du masque qui sont plus petits que 350 pixels. Je garde ensuite seulement l'object avec le plus grand aire. Voici un exemple de masque après ce traitement :

Jumelage des photos

Les photos sont ensuite jumelées une à une pour créer une mosaïque finale. On copie simplement les pixels du masque de l'image traitée dans l'image finale pour tous les canaux. Je termine par applique un filtre gaussien pour lisser l'image finale.

Résultats finaux

Voici les résultat sur trois vidéos différents avec un nombre d'images différents :

3 images

4 images

6 images

8 images

12 images

3 images

4 images

6 images

8 images

12 images

3 images

4 images

6 images

Interprétation des résultats

On peut voir que l'image résultante est acceptable malgré la simplicité de l'algorithme. On peut imaginer qu'il y aura des erreurs si la couleur de fond et la couleur de l'objet est trop similaire. On peut voir ce genre d'erreur si on zoom sur le pantalon noir quand le fond est brun comme le bois. Aussi, la pointe du ski est parfois oubliée puisqu'elle est très mince. Voici deux exemples d'erreurs de ce genre :

Conclusion

Malheureusement mon algorithme de segmentation par "graph cut" est trop lent pour être utilisé. J'aurais bien aimé le tester pour renforcir mon algorithme déjà en place. J'ai laissé tout de même mon implémentation de "graph cut" dans mon dépot.