Créer des GIF avec OpenCV



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:

  1. Comme réponse ou objection à quelqu'un qui n'approuve pas quelque chose que vous avez fait / dit («Traitez-le»)
  2. 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:

  1. Détection des visages à l'aide de techniques d'apprentissage approfondi
  2. Utilisation de la bibliothèque dlib pour détecter les repères faciaux et extraire les zones des yeux
  3. Comment calculer l'angle de rotation entre les yeux en fonction des informations reçues
  4. 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 GIF

Opencv 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 Python

Il 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 ça


Fig. 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-le


Fig. 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 ça

Des 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:

 #    from imutils import face_utils from imutils import paths import numpy as np import argparse import imutils import shutil import json import dlib import cv2 import sys import os 

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): #     (, )  #    (sH, sW) = fg.shape[:2] (x, y) = coords #          #  ,   , **  # ,    overlay = np.zeros(bg.shape, dtype="uint8") overlay[y:y + sH, x:x + sW] = fg # - , **  ** # ,    ,    # ,       alpha = np.zeros(bg.shape[:2], dtype="uint8") alpha[y:y + sH, x:x + sW] = fgMask alpha = np.dstack([alpha] * 3) #  -   , #   - output = alpha_blend(overlay, bg, alpha) #   return output 

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): #  ,    - #        [0, 1] fg = fg.astype("float") bg = bg.astype("float") alpha = alpha.astype("float") / 255 #  - fg = cv2.multiply(alpha, fg) bg = cv2.multiply(1 - alpha, bg) #     ,    output = cv2.add(fg, bg) #   return output.astype("uint8") 

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): #        imagePaths = sorted(list(paths.list_images(inputPath))) #      lastPath = imagePaths[-1] imagePaths = imagePaths[:-1] #   imagemagick 'convert'  #  GIF      #   ( ) cmd = "convert -delay {} {} -delay {} {} -loop {} {}".format( delay, " ".join(imagePaths), finalDelay, lastPath, loop, outputPath) os.system(cmd) 

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:

 #      ap = argparse.ArgumentParser() ap.add_argument("-c", "--config", required=True, help="path to configuration file") ap.add_argument("-i", "--image", required=True, help="path to input image") ap.add_argument("-o", "--output", required=True, help="path to output GIF") args = vars(ap.parse_args()) 

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:

 #    JSON, #     config = json.loads(open(args["config"]).read()) sg = cv2.imread(config["sunglasses"]) sgMask = cv2.imread(config["sunglasses_mask"]) #    (  ),   #  ,  ,     #   GIF- shutil.rmtree(config["temp_dir"], ignore_errors=True) os.makedirs(config["temp_dir"]) 

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:

 # load our OpenCV face detector and dlib facial landmark predictor print("[INFO] loading models...") detector = cv2.dnn.readNetFromCaffe(config["face_detector_prototxt"], config["face_detector_weights"]) predictor = dlib.shape_predictor(config["landmark_predictor"]) 

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 DNN

Chargez 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 visage

Plus loin dans ce script, nous n'extrayons que le contour des yeux.

Passons à autre chose, trouvons le visage:

 #       image = cv2.imread(args["image"]) (H, W) = image.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) #        print("[INFO] computing object detections...") detector.setInput(blob) detections = detector.forward() #       ,  #  ,      i = np.argmax(detections[0, 0, :, 2]) confidence = detections[0, 0, i, 2] #    if confidence < config["min_confidence"]: print("[INFO] no reliable faces found") sys.exit(0) 

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:

 #   (x, y)  #    box = detections[0, 0, i, 3:7] * np.array([W, H, W, H]) (startX, startY, endX, endY) = box.astype("int") #    dlib    #       rect = dlib.rectangle(int(startX), int(startY), int(endX), int(endY)) shape = predictor(image, rect) shape = face_utils.shape_to_np(shape) #        ,  #     (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] leftEyePts = shape[lStart:lEnd] rightEyePts = shape[rStart:rEnd] 

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:

 #       leftEyeCenter = leftEyePts.mean(axis=0).astype("int") rightEyeCenter = rightEyePts.mean(axis=0).astype("int") #      dY = rightEyeCenter[1] - leftEyeCenter[1] dX = rightEyeCenter[0] - leftEyeCenter[0] angle = np.degrees(np.arctan2(dY, dX)) - 180 #      ,  #      sg = imutils.rotate_bound(sg, angle) #     **  ,    #   —       # 90%       sgW = int((endX - startX) * 0.9) sg = imutils.resize(sg, width=sgW) #      ( ,   #  ),      #     - —   #       , #     sgMask = cv2.cvtColor(sgMask, cv2.COLOR_BGR2GRAY) sgMask = cv2.threshold(sgMask, 0, 255, cv2.THRESH_BINARY)[1] sgMask = imutils.rotate_bound(sgMask, angle) sgMask = imutils.resize(sgMask, width=sgW, inter=cv2.INTER_NEAREST) 

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:

 #    ,   #  N       #    steps = np.linspace(0, rightEyeCenter[1], config["steps"], dtype="int") # start looping over the steps for (i, y) in enumerate(steps): #      #  ,    **    #  ,       #   shiftX = int(sg.shape[1] * 0.25) shiftY = int(sg.shape[0] * 0.35) y = max(0, y - shiftY) # add the sunglasses to the image output = overlay_image(image, sg, sgMask, (rightEyeCenter[0] - shiftX, y)) 

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:

  #    ,    #  "DEAL WITH IT"   if i == len(steps) - 1: #   "DEAL WITH IT"  , #   dwi = cv2.imread(config["deal_with_it"]) dwiMask = cv2.imread(config["deal_with_it_mask"]) dwiMask = cv2.cvtColor(dwiMask, cv2.COLOR_BGR2GRAY) dwiMask = cv2.threshold(dwiMask, 0, 255, cv2.THRESH_BINARY)[1] #       80%   #  oW = int(W * 0.8) dwi = imutils.resize(dwi, width=oW) dwiMask = imutils.resize(dwiMask, width=oW, inter=cv2.INTER_NEAREST) #  ,   ,  #   oX = int(W * 0.1) oY = int(H * 0.8) output = overlay_image(output, dwi, dwiMask, (oX, oY)) 

À 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:

  #      p = os.path.sep.join([config["temp_dir"], "{}.jpg".format( str(i).zfill(8))]) cv2.imwrite(p, output) #      ,     #   GIF- print("[INFO] creating GIF...") create_gif(config["temp_dir"], args["output"], config["delay"], config["final_delay"], config["loop"]) #  --    print("[INFO] cleaning up...") shutil.rmtree(config["temp_dir"], ignore_errors=True) 

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 Python

Ici, vous pouvez voir le GIF créé en utilisant OpenCV et ImageMagick. Les actions suivantes y sont effectuées:

  1. Détection correcte de mon visage.
  2. Localisation des yeux et calcul de leurs centres.
  3. 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 2

Me 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 soleil

Ré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_utilsutilise 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. ;)

Source: https://habr.com/ru/post/fr429024/


All Articles