Ce tutoriel vous montrera comment créer des GIF animés en utilisant OpenCV, Python et ImageMagick. Combinez ensuite ces méthodes pour créer un générateur de mèmes avec OpenCV!
Nous devons tous rire de temps en temps. Et peut-être que la meilleure façon de trouver lulza est avec les mèmes. Certains de mes favoris:
- Kermit la grenouille: «Mais ce n'est pas mon affaire»
- Chat grincheux
- Échec épique
- Good guy greg
Mais pour moi personnellement, aucun de ces mèmes ne peut être comparé au mème "Deal With It" ("Traitez-le" ou "Comprenez-le vous-même"), dont un exemple est donné au début de l'article.Il est généralement utilisé dans les cas suivants:
- Comme réponse ou objection à quelqu'un qui n'approuve pas quelque chose que vous avez fait / dit («Traitez-le»)
- Mettre vos lunettes comme si vous partiez et laisser la personne seule avec le problème («Comprenez-le vous-même»)
Il y a quelques années, j'ai lu un article amusant sur le blog de l'auteur, dont je ne me souviens pas comment générer de tels mèmes en utilisant la vision par ordinateur. La semaine dernière, je ne pouvais pas trouver ce guide nulle part, donc en tant que blogueur, expert en vision par ordinateur et expert sur les mèmes, j'ai décidé d'écrire un tutoriel moi-même! (Au fait, si vous connaissez accidentellement la source d'origine, faites-le moi savoir afin que je puisse remercier l'auteur.
UPD: Je viens de trouver l'article original du blog de Kirk Kaiser
MakeArtWithPython ).
Développer un générateur de mèmes sur OpenCV nous apprendra un certain nombre de compétences pratiques précieuses, notamment:
- Détection des visages à l'aide de techniques d'apprentissage approfondi
- Utilisation de la bibliothèque dlib pour détecter les repères faciaux et extraire les zones des yeux
- Comment calculer l'angle de rotation entre les yeux en fonction des informations reçues
- Et enfin, comment générer des GIF animés en utilisant OpenCV (avec un peu d'aide d'ImageMagick)
Ce guide doit être amusant et divertissant - et en même temps vous enseigner de précieuses compétences en programmation de vision par ordinateur qui sont utiles dans le monde réel.
Création de GIF avec OpenCV
Dans la première partie du guide, nous discuterons des conditions et des dépendances nécessaires pour ce projet, y compris la configuration appropriée de l'environnement de développement.
Ensuite, considérez la structure du projet / catalogue pour notre générateur OpenCV GIF.
Dès que nous comprendrons la structure du projet, nous considérerons: 1) notre fichier de configuration; 2) le script Python responsable de la création de GIF avec OpenCV.
Enfin, nous évaluerons les résultats du programme sur le mème populaire «Deal With It».
Prérequis et dépendances
Fig. 1. Nous utiliserons OpenCV, dlib et ImageMagick pour créer des GIFOpencv et dlib
OpenCV est nécessaire pour déterminer les visages dans le cadre et le traitement d'image de base. Suivez l'un de mes
guides d'installation d'OpenCV si OpenCV n'est pas installé sur le système.
Nous utilisons Dlib pour détecter les repères faciaux, ce qui nous permet de trouver deux yeux sur le visage et de mettre des lunettes de soleil. Vous pouvez
installer dlib en utilisant cette instruction .
Imagemagick
Si vous n'êtes pas familier avec
ImageMagick , alors en vain. Il s'agit d'un outil en ligne de commande multiplateforme avec de nombreuses fonctionnalités de traitement d'image.
Voulez-vous convertir PNG / JPG en PDF avec une seule commande? Pas de problème.
Il existe plusieurs images à partir desquelles vous devez créer un PDF de plusieurs pages? Facilement.
Besoin de dessiner des polygones, des lignes et d'autres formes? Et c'est possible.
Que diriez-vous de l'étalonnage des couleurs par lots ou du redimensionnement de toutes les images avec une seule commande? Pour ce faire, vous n'avez pas besoin d'écrire quelques lignes en Python pour OpenCV.
ImageMagick génère également des GIF à partir de n'importe quelle image.
Pour installer ImageMagick sur Ubuntu (ou Raspbian), utilisez simplement apt:
Création de GIF avec OpenCVShell
$ sudo apt-get install imagemagick
Sur macOS, vous pouvez utiliser HomeBrew:
$ brew install imagemagick
imutils
Dans la plupart des articles, des cours et des livres, j'utilise mon
package de traitement d'image
imutils pratique. Il est installé sur un système ou un environnement virtuel utilisant pip:
$ pip install imutils
Structure du projet
Fig. 2. La structure du projet comprend deux répertoires, un fichier de configuration et un script PythonIl existe deux catalogues dans notre projet:
images/
: exemples d'images d'entrée pour lesquelles nous voulons créer un GIF animé. J'ai trouvé quelques images avec moi, mais n'hésitez pas à ajouter les vôtres.assets/
: ce dossier contient notre détecteur de visage, détecteur de repère de visage et toutes les images + masques associés. Avec ces ressources, nous mettrons des points et du texte sur les images originales du premier dossier.
En raison du grand nombre de paramètres configurables, j'ai décidé de créer un fichier de configuration JSON qui: 1) facilitera l'édition des paramètres; 2) nécessitera moins d'arguments de ligne de commande. Tous les paramètres de configuration requis pour ce projet sont contenus dans
config.json
.
Considérez le contenu de
config.json
et
create_gif.py
.
Remarque Per.: Le code du projet et le manuel de 17 pages sur la vision par ordinateur, l'apprentissage automatique et OpenCV sont publiés après l'enregistrement (miroir: code source , manuel ).Génération de GIF avec OpenCV
Alors, continuons et commençons à créer notre générateur GIF OpenCV!
Contenu du fichier de configuration JSON
Commençons par le fichier de configuration JSON, puis passons au script Python.
Ouvrez un nouveau fichier
config.json
et insérez les paires clé / valeur suivantes:
Création de GIF avec OpenCVPython
{ "face_detector_prototxt": "assets/deploy.prototxt", "face_detector_weights": "assets/res10_300x300_ssd_iter_140000.caffemodel", "landmark_predictor": "assets/shape_predictor_68_face_landmarks.dat",
Ce sont des fichiers de modèle de
détecteur de visage OpenCV en apprentissage profond .
La dernière ligne est le chemin vers le prédicteur de face dlib.
Et maintenant, nous avons quelques chemins vers les fichiers image:
"sunglasses": "assets/sunglasses.png", "sunglasses_mask": "assets/sunglasses_mask.png", "deal_with_it": "assets/deal_with_it.png", "deal_with_it_mask": "assets/deal_with_it_mask.png",
Ce sont les chemins d'accès à nos lunettes de soleil, du texte et des masques assortis pour eux, qui sont indiqués ci-dessous.
Tout d'abord, des lunettes de soleil fantaisie et un masque:
Fig. 3. Vous n'aimez pas les lunettes avec pixels? Juste supporter çaFig. 4. Vous ne comprenez pas pourquoi vous avez besoin d'un masque pour lunettes de soleil? Il suffit de le supporter - ou de lire le reste de l'article pour la réponse.Et maintenant, notre texte est «DEAL AVEC ELLE» et le masque:
Fig. 5. Détestez-vous Helvetica Neue Condensed? Traitez-leFig. 6: Ce masque vous permet de dessiner une bordure autour du texte. Oh, peut-être que vous ne voulez pas, voulez-vous une frontière? Eh bien, supporte çaDes masques sont nécessaires pour superposer l'image correspondante sur la photo: nous y reviendrons plus tard.
Maintenant, définissez certains paramètres pour le générateur de memes:
"min_confidence": 0.5, "steps": 20, "delay": 5, "final_delay": 250, "loop": 0, "temp_dir": "temp" }
Voici les définitions de chacun des paramètres:
min_confidence
: min_confidence
minimale de détection de visage requise.steps
: nombre d'images dans l'animation finale. Chaque «étape» déplace les lunettes de soleil de la bordure supérieure vers la cible (c'est-à-dire jusqu'aux yeux).delay
: délai entre les images en centièmes de seconde.final_delay
: retard de la dernière image en centièmes de seconde (utile dans ce contexte, car nous voulons que le texte s'affiche plus longtemps que le reste des images).loop
: une valeur nulle indique que le GIF se répète pour toujours, sinon spécifiez un entier positif pour le nombre de répétitions de l'animation.temp_dir
: le répertoire temporaire dans lequel chacune des images sera stockée avant de créer le GIF final.
Mèmes, GIF et OpenCV
Nous avons créé le fichier de configuration JSON, passons maintenant au vrai code.
Ouvrez un nouveau fichier, nommez-le
create_gif.py
et collez le code suivant:
Ici, nous importons les packages nécessaires. En particulier, nous utiliserons imutils, dlib et OpenCV. Pour installer ces dépendances, consultez la section Prérequis et dépendances ci-dessus.
Maintenant, le script a les packages nécessaires, définissons donc la fonction
overlay_image
:
def overlay_image(bg, fg, fgMask, coords):
La fonction
overlay_image
impose un premier plan (
fg
) sur le dessus de l'image d'arrière-plan (
bg
) aux coordonnées de coordonnées
( coordonnées
(x, y) ), réalisant une transparence alpha sur le masque de premier plan
fgMask
.
Pour vous familiariser avec les bases d'OpenCV, telles que l'utilisation de masques, assurez-vous de lire
ce guide .
Pour terminer le processus de fusion, effectuez une fusion alpha:
def alpha_blend(fg, bg, alpha):
Cette implémentation du mélange alpha est également disponible
sur le blog LearnOpenCV .
Essentiellement, nous convertirons le premier plan, l'arrière-plan et le canal alpha en nombres à virgule flottante dans la plage
[0, 1] . Ensuite, nous effectuons un mélange alpha, ajoutons le premier plan et l'arrière-plan pour obtenir le résultat que nous retournons à la fonction appelante.
Nous allons également créer une fonction d'assistance qui permet de générer des GIF à partir d'un ensemble de chemins d'image à l'aide d'ImageMagick et de la commande
convert
:
def create_gif(inputPath, outputPath, delay, finalDelay, loop):
La fonction
create_gif
prend un ensemble d'images et les recueille dans des animations GIF avec un délai spécifié entre les images et les boucles. ImageMagick traite tout cela - nous enveloppons simplement la commande
convert
dans une fonction qui traite dynamiquement divers paramètres.
Pour voir les arguments de
convert
disponibles,
consultez la documentation . Vous y verrez combien de fonctions cette équipe a!
Plus précisément dans cette fonction, nous:
- Prenez
imagePaths
. - Choisissez le chemin de la dernière image, qui aura un délai séparé.
- Réaffectez
imagePaths
pour exclure le dernier chemin. - Nous assemblons une commande avec des arguments de ligne de commande, puis demandons au système d'exploitation de
convert
pour créer des animations GIF.
Attribuez au script ses propres arguments de ligne de commande:
Nous avons trois arguments de ligne de commande qui sont traités au moment de l'exécution:
--config
: chemin d'accès au fichier de configuration JSON. Nous avons examiné le fichier de configuration dans la section précédente.--image
: chemin d'accès à l'image d'entrée par rapport à laquelle l'animation est créée (c'est-à-dire détection d'un visage, ajout de lunettes de soleil, puis texte).--output
: chemin vers le GIF résultant.
Chacun de ces arguments est requis lors de l'exécution du script sur la ligne de commande / le terminal.
Téléchargez le fichier de configuration, ainsi que les lunettes et le masque correspondant:
Ici, nous chargeons le fichier de configuration (qui pourrait être disponible à l'avenir sous forme de dictionnaire Python). Chargez ensuite les lunettes de soleil et le masque.
S'il reste quelque chose du script précédent, supprimez le répertoire temporaire, puis recréez le répertoire temporaire vide. Le dossier temporaire contiendra chaque image individuelle de l'animation GIF.
Maintenant, chargez le
détecteur de visage d'apprentissage profond OpenCV en mémoire:
Pour ce faire, appelez
cv2.dnn.readNetFromCaffe
. Le module
dnn
est uniquement disponible dans OpenCV 3.3 ou version ultérieure. Un détecteur de visage détectera la présence de visages dans l'image:
Fig. 7. Fonctionnement du détecteur de visage à l'aide d'OpenCV DNNChargez ensuite le
prédicteur de repère dlib face . Il vous permettra de localiser les structures individuelles: yeux, sourcils, nez, bouche et menton:
Fig. 8. Les repères découverts par dlib se superposent à mon visagePlus loin dans ce script, nous n'extrayons que le contour des yeux.
Passons à autre chose, trouvons le visage:
Dans ce bloc, nous procédons comme suit:
- Téléchargez l'
image
originale. - Nous construisons un
blob
à envoyer au détecteur de visage d'un réseau neuronal. Cet article décrit le fonctionnement de blobFromImage
d'OpenCV. - Exécutez la procédure de détection de visage.
- Nous trouvons la personne ayant la valeur de probabilité la plus élevée et la comparons avec le seuil de probabilité minimum acceptable. Si les critères ne sont pas remplis, quittez simplement le script. Sinon, continuez.
Maintenant, nous allons extraire le visage et calculer les points de repère:
Pour extraire le visage et trouver des repères faciaux, nous procédons comme suit:
- Nous extrayons les coordonnées de la boîte englobante autour du visage.
- Créez un objet
rectangle
dans dlib et appliquez la localisation de face. - Nous
leftEyePts
coordonnées (x, y) de leftEyePts
et rightEyePts
, respectivement.
Compte tenu des coordonnées des yeux, vous pouvez calculer où et comment placer les lunettes de soleil:
Tout d'abord, nous calculons le centre de chaque œil, puis l'angle entre les centroïdes. La même opération est effectuée avec l'
alignement horizontal
du visage dans le cadre .
Vous pouvez maintenant faire pivoter et redimensionner les lunettes. Notez que nous utilisons
la fonction rotation_liée , pas seulement la
rotate
, afin que OpenCV ne coupe pas les parties qui ne sont pas visibles après la conversion affine.
Les mêmes opérations qui ont été appliquées aux lunettes s'appliquent au masque. Mais vous devez d'abord le convertir en nuances de gris et binariser, car les masques sont toujours binaires. Ensuite, nous faisons pivoter et redimensionnons le masque de la même manière que pour les lunettes.
Remarque: notez que lors du redimensionnement du masque, nous utilisons l'interpolation pour les points voisins les plus proches, car le masque ne doit avoir que deux valeurs (0 et 255). D'autres méthodes d'interpolation sont plus esthétiques, mais ne conviennent pas aux masques. Ici, vous pouvez obtenir des informations supplémentaires sur l'interpolation aux points voisins les plus proches.Les trois autres blocs de code créent des cadres pour l'animation GIF:
Les verres tombent du haut de l'image. Sur chaque image, ils sont affichés plus près du visage jusqu'à ce qu'ils couvrent leurs yeux. En utilisant la variable
"steps"
dans le fichier de configuration JSON, nous générons des coordonnées y pour chaque trame. Pour ce faire, sans trop d'effort, nous utilisons la fonction
linspace
de NumPy.
Les lignes avec un léger décalage vers la gauche et vers le haut peuvent sembler un peu étranges, mais elles sont nécessaires pour s'assurer que les lunettes couvrent les yeux dans leur ensemble, et ne se déplacent pas seulement au point où se trouve le centre de l'œil. J'ai déterminé empiriquement des pourcentages pour calculer le décalage le long de chaque axe. La ligne suivante n'assure aucune valeur négative.
En utilisant la fonction
overlay_image
,
overlay_image
générons la trame de
output
finale.
Maintenant, appliquez le texte "DEAL WITH IT" en utilisant un autre masque:
À la dernière étape, nous imposons le texte, qui est en réalité une autre image.
J'ai décidé d'utiliser une image car les capacités de rendu des polices OpenCV sont assez limitées. De plus, je voulais ajouter une ombre et une bordure autour du texte, qu'OpenCV ne sait pas encore comment.
Dans le reste de ce code, nous chargeons à la fois l'image et le masque, puis effectuons un mélange alpha pour générer le résultat final.
Il ne reste plus qu'à enregistrer chaque image sur le disque avec la création ultérieure d'animation GIF:
Nous écrivons le résultat sur le disque. Après avoir généré toutes les images, nous appelons la fonction
create_gif
pour créer le fichier d'animation GIF. N'oubliez pas qu'il s'agit d'un shell qui transmet des paramètres à l'outil de ligne de commande de
convert
ImageMagick.
Enfin, supprimez le répertoire de sortie temporaire et les fichiers d'image individuels.
Résultats
Maintenant, la partie amusante: voyons ce que notre générateur de mèmes a créé!
Assurez-vous de
télécharger le code source, des exemples d'images et des modèles d'apprentissage approfondi. Ouvrez ensuite un terminal et exécutez la commande suivante:
$ python create_gif.py --config config.json --image images/adrian.jpg \ --output adrian_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Figure 9. Animation GIF générée avec OpenCV et ImageMagick avec ce script PythonIci, vous pouvez voir le GIF créé en utilisant OpenCV et ImageMagick. Les actions suivantes y sont effectuées:
- Détection correcte de mon visage.
- Localisation des yeux et calcul de leurs centres.
- Les lunettes tombent correctement sur le visage.
Les lecteurs de mon blog savent que je suis un gros nerd à Jurassic Park et le mentionnent souvent dans mes livres, mes cours et mes guides d'étude.
Vous n'aimez pas
Jurassic Park ?
Ok, voici ma réponse:
$ python create_gif.py --config config.json --image images/adrian_jp.jpg \ --output adrian_jp_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 10. Animation GIF OpenCV basée sur une photographie de la récente projection de Jurassic World 2Me voici au spectacle "Jurassic World: 2" dans un T-shirt thématique, avec un verre de lumière et un livre de collection.
Histoire amusante:
Il y a cinq ou six ans, ma femme et moi avons visité le parc à thème Epcot Center à Disney World, en Floride.
Nous avons décidé de faire un voyage pour nous éloigner des hivers rigoureux du Connecticut et nous avions désespérément besoin de soleil.
Malheureusement, en Floride, il pleuvait tout le temps et la température dépassait à peine 10 ° C.
Près des jardins canadiens, Trisha a pris une photo de moi: elle dit que je ressemble à un vampire avec une peau pâle, des vêtements sombres et une capuche, sur le fond des jardins luxuriants derrière:
$ python create_gif.py --config config.json --image images/vampire.jpg \ --output vampire_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 11. En utilisant OpenCV et Python, vous pouvez créer ce meme ou un autre GIF animéLe même soir, Trisha a publié une photo sur les réseaux sociaux - j'ai dû la supporter.
Ceux d'entre vous qui ont assisté à PyImageConf 2018 (
lire la critique ) savent que je suis toujours ouvert aux blagues. Voici un exemple:
Question: Pourquoi le coq traverse-t-il la route? $ python create_gif.py --config config.json --image images/rooster.jpg \ --output rooster_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 12. Le visage est reconnu même avec un faible contraste, et OpenCV traite correctement la photo et abaisse les lunettes de soleilRéponse: Je ne dirai pas la réponse - supporte cela.Enfin, nous concluons le guide d'aujourd'hui par un bon mème.Il y a environ six ans, mon père et moi avons adopté un petit beagle, Gemma.Ici, vous pouvez voir Gemma sur mon épaule: $ python create_gif.py --config config.json --image images/pupper.jpg \ --output pupper_out.gif [INFO] loading models... [INFO] computing object detections... [INFO] creating GIF... [INFO] cleaning up...
Fig. 13. Gemma est délicieuse. Tu ne crois pas? Alors "acceptez-le!"Ne convenez pas qu'elle est mignonne? Traitez-le.Vous avez une erreur AttributeError?
Ne t'inquiète pas!Si vous avez vu cette erreur: $ python create_gif.py --config config.json --image images/adrian.jpg \ --output adrian_out.gif ... Traceback (most recent call last): File "create_gif.py", line 142, in <module> (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] AttributeError: module 'imutils.face_utils' has no attribute 'FACIAL_LANDMARKS_IDXS'
... alors il vous suffit de mettre à jour le paquet imutils: $ pip install --upgrade imutils Collecting imutils ... Successfully installed imutils-0.5.1
Pourquoi?
Par défaut, il imutils.face_utils
utilise un détecteur de point de repère de 68 points intégré à dlib (comme dans cet article). Il existe un détecteur 5 points plus rapide , qui fonctionne désormais également avec les imutils. J'ai récemment mis à jour des imutils pour prendre en charge les deux détecteurs (vous pouvez donc voir une erreur).Résumé
Dans le didacticiel d'aujourd'hui, vous avez appris à créer des GIF à l'aide d'OpenCV.Pour rendre la leçon amusante, nous avons utilisé OpenCV pour générer l'animation GIF «Deal With It», un mème populaire (et mon préféré) qui se trouve sous une forme ou une autre sur presque tous les sites de réseaux sociaux.Dans le processus, nous avons utilisé la vision par ordinateur et l'apprentissage en profondeur pour résoudre plusieurs problèmes pratiques:- Identification des personnes
- Prévoyez des repères sur le visage
- Identification des zones du visage (dans ce cas, l'œil)
- Calcul de l'angle entre les yeux pour aligner le visage
- Créez des mélanges transparents avec le mélange alpha
Enfin, nous avons pris un ensemble d'images générées et créé un GIF animé en utilisant OpenCV et ImageMagick.J'espère que vous avez apprécié le tutoriel d'aujourd'hui!Si cela vous a plu, laissez un commentaire et faites le moi savoir.Eh bien, si vous ne l'aimiez pas, cela n'a pas d'importance, il suffit de le supporter. ;)