Crea GIFs con OpenCV



Este tutorial le mostrará cómo crear GIF animados usando OpenCV, Python e ImageMagick. ¡Luego combina estos métodos para crear un generador de memes con OpenCV!

Todos necesitamos reírnos de vez en cuando. Y quizás la mejor manera de encontrar a Lulza es con memes. Algunos de mis favoritos:

  • Kermit the Frog: "Pero no es asunto mío"
  • Gato gruñón
  • Fracaso épico
  • Buen chico greg

Pero para mí personalmente, ninguno de estos memes puede compararse con el meme "Lidia con él" ("Lidia con él" o "Comprendelo tú mismo"), un ejemplo del cual se da al comienzo del artículo.

Por lo general, se usa en los siguientes casos:

  1. Como una respuesta u objeción a alguien que no aprueba algo que usted ha hecho / dicho ("Enfréntelo")
  2. Ponerse las gafas como si se fuera y dejar a la persona sola con el problema ("Comprenda usted mismo")

Hace unos años leí un artículo divertido en el blog del autor, que no recuerdo cómo generar esos memes usando la visión por computadora. La semana pasada no pude encontrar esta guía en ningún lado, así que como blogger, experto en visión artificial y conocedor de memes, ¡decidí escribir un tutorial yo mismo! (Por cierto, si accidentalmente conoce la fuente original, avíseme para agradecerle al autor. UPD: Acabo de encontrar el artículo original del blog MakeArtWithPython de Kirk Kaiser).

El desarrollo de un generador de memes en OpenCV nos enseñará varias habilidades prácticas valiosas, que incluyen:

  1. Detección de rostros utilizando técnicas de aprendizaje profundo
  2. Usando la biblioteca dlib para detectar puntos de referencia faciales y extraer áreas de los ojos
  3. Cómo calcular el ángulo de rotación entre los ojos en función de la información recibida
  4. Y finalmente, cómo generar GIF animados usando OpenCV (con un poco de ayuda de ImageMagick)

Esta guía debe ser divertida y entretenida y, al mismo tiempo, enseñarle valiosas habilidades de programación de visión por computadora que son útiles en el mundo real.

Crear GIF con OpenCV


En la primera parte de la guía, discutiremos las condiciones y dependencias necesarias para este proyecto, incluida la configuración adecuada del entorno de desarrollo.

Luego considere la estructura del proyecto / catálogo para nuestro generador de GIF OpenCV.

Tan pronto como comprendamos la estructura del proyecto, consideraremos: 1) nuestro archivo de configuración; 2) el script Python responsable de crear GIF con OpenCV.

Finalmente, evaluaremos los resultados del programa sobre el popular meme "Deal With It".

Prerrequisitos y dependencias



Fig. 1. Usaremos OpenCV, dlib e ImageMagick para crear GIF

Opencv y dlib


Se necesita OpenCV para determinar las caras en el marco y el procesamiento básico de imágenes. Siga una de mis guías de instalación de OpenCV si OpenCV no está instalado en el sistema.

Usamos Dlib para detectar puntos de referencia faciales, lo que nos permite encontrar dos ojos en la cara y ponernos gafas de sol. Puede instalar dlib usando estas instrucciones .

Imagemagick


Si no está familiarizado con ImageMagick , entonces en vano. Es una herramienta de línea de comandos multiplataforma con muchas funciones de procesamiento de imágenes.

¿Quieres convertir PNG / JPG a PDF con un solo comando? No hay problema

¿Hay varias imágenes de las que necesita hacer un PDF de varias páginas? Fácilmente

¿Necesita dibujar polígonos, líneas y otras formas? Y es posible.

¿Qué tal la clasificación de color por lotes o el cambio de tamaño de todas las imágenes con un comando? Para hacer esto, no necesita escribir algunas líneas en Python para OpenCV.

ImageMagick también genera GIF a partir de cualquier imagen.

Para instalar ImageMagick en Ubuntu (o Raspbian) simplemente use apt:

Crear GIF con OpenCVShell

$ sudo apt-get install imagemagick 

En macOS, puede usar HomeBrew:

 $ brew install imagemagick 

inútiles


En la mayoría de los artículos, cursos y libros, utilizo mi conveniente paquete de procesamiento de imágenes imutils . Se instala en un sistema o entorno virtual utilizando pip:

 $ pip install imutils 

Estructura del proyecto



Fig. 2. La estructura del proyecto incluye dos directorios, un archivo de configuración y un script Python

Hay dos catálogos en nuestro proyecto:

  • images/ : ejemplos de imágenes de entrada para las que queremos hacer un GIF animado. Encontré algunas imágenes conmigo, pero siéntase libre de agregar las suyas.
  • assets/ : esta carpeta contiene nuestro detector de rostro, detector de hito facial y todas las imágenes + máscaras relacionadas. Con estos recursos, colocaremos puntos y texto en las imágenes originales de la primera carpeta.

Debido a la gran cantidad de parámetros configurables, decidí crear un archivo de configuración JSON, que: 1) facilitará la edición de parámetros; 2) requerirá menos argumentos de línea de comando. Todos los parámetros de configuración necesarios para este proyecto están contenidos en config.json .

Considere los contenidos de config.json y create_gif.py .

Nota Per .: El código del proyecto y el manual de 17 páginas sobre visión por computadora, aprendizaje automático y OpenCV se emiten después del registro (espejo: código fuente , manual ).

Generación GIF con OpenCV


¡Entonces, continuemos y comencemos a crear nuestro generador de GIF OpenCV!

Contenido del archivo de configuración JSON


Comencemos con el archivo de configuración JSON y luego pasemos al script Python.

Abra un nuevo archivo config.json e inserte los siguientes pares clave / valor:

Crear GIF con 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", 

Estos son archivos de modelo de detector de rostro OpenCV en aprendizaje profundo .

La última línea es la ruta al predictor de cara dlib.

Y ahora tenemos algunas rutas a los archivos de imagen:

 "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", 

Estos son los caminos a nuestras gafas de sol, texto y máscaras a juego para ellos, que se muestran a continuación.

En primer lugar, gafas de sol elegantes y una máscara:


Fig. 3. ¿No te gustan las gafas con píxeles? Solo aguantalo


Fig. 4. ¿No entiendes por qué necesitas una máscara para gafas de sol? Solo aguantalo, o lee el resto del artículo para obtener la respuesta.

Y ahora nuestro texto es "TRATE CON ÉL" y la máscara:


Fig. 5. ¿Odias Helvetica Neue Condensed? Lidiar con eso


Fig. 6: Esta máscara te permite dibujar un borde alrededor del texto. Oh, tal vez no quieras, ¿quieres un borde? Bueno, aguantalo

Se necesitan máscaras para superponer la imagen correspondiente en la foto: trataremos esto más adelante.

Ahora configure algunos parámetros para el generador de memes:

  "min_confidence": 0.5, "steps": 20, "delay": 5, "final_delay": 250, "loop": 0, "temp_dir": "temp" } 

Aquí están las definiciones para cada uno de los parámetros:

  • min_confidence : min_confidence mínima requerida de detección de rostros.
  • steps : número de cuadros en la animación final. Cada "paso" mueve las gafas de sol desde el borde superior hacia el objetivo (es decir, hacia los ojos).
  • delay : retraso entre cuadros en centésimas de segundo.
  • final_delay : retraso del último fotograma en centésimas de segundo (útil en este contexto, ya que queremos que el texto se muestre más tiempo que el resto de los fotogramas).
  • loop : un valor cero indica que el GIF se repite para siempre; de ​​lo contrario, especifique un número entero positivo para el número de repeticiones de la animación.
  • temp_dir : el directorio temporal en el que se almacenarán cada uno de los marcos antes de crear el GIF final.

Memes, GIF y OpenCV


Creamos el archivo de configuración JSON, ahora pasemos al código real.

Abra un nuevo archivo, create_gif.py nombre create_gif.py y pegue el siguiente código:

 #    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 

Aquí importamos los paquetes necesarios. En particular, usaremos imutils, dlib y OpenCV. Para instalar estas dependencias, consulte la sección Requisitos previos y dependencias más arriba.

Ahora el script tiene los paquetes necesarios, así overlay_image definamos la función 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 función overlay_image impone un primer plano ( fg ) en la parte superior de la imagen de fondo ( bg ) en las coordenadas de las coordenadas ( coordenadas (x, y) ), realizando la transparencia alfa sobre la máscara de primer plano fgMask .

Para familiarizarse con los conceptos básicos de OpenCV, como trabajar con máscaras, asegúrese de leer esta guía .

Para completar el proceso de mezcla, realice una mezcla alfa:

 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") 

Esta implementación de mezcla alfa también está disponible en el blog LearnOpenCV .

En esencia, convertiremos el primer plano, el fondo y el canal alfa a números de coma flotante en el rango [0, 1] . Luego realizamos una mezcla alfa, agregamos el primer plano y el fondo para obtener el resultado de que volvemos a la función de llamada.

También crearemos una función auxiliar que permita generar GIF a partir de un conjunto de rutas de imagen utilizando ImageMagick y el comando de 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 función create_gif toma un conjunto de imágenes y las recopila en animaciones GIF con un retraso especificado entre cuadros y bucles. ImageMagick procesa todo esto: simplemente envolvemos el comando de convert en una función que procesa dinámicamente varios parámetros.

Para ver los argumentos de convert disponibles, consulte la documentación . ¡Allí verá cuántas funciones tiene este equipo!

Específicamente en esta función, nosotros:

  • Tome imagePaths .
  • Elija la ruta de la última imagen, que tendrá un retraso por separado.
  • Reasigne imagePaths para excluir la última ruta.
  • Ensamblamos un comando con argumentos de línea de comando y luego le indicamos al sistema operativo que convert para crear animaciones GIF.

Asigne al script sus propios argumentos de línea de comando:

 #      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()) 

Tenemos tres argumentos de línea de comandos que se procesan en tiempo de ejecución:

  • --config : ruta al archivo de configuración JSON. Revisamos el archivo de configuración en la sección anterior.
  • --image : ruta a la imagen de entrada contra la cual se crea la animación (es decir, detectar una cara, agregar gafas de sol y luego texto).
  • --output : ruta al GIF resultante.

Cada uno de estos argumentos es obligatorio al ejecutar el script en la línea de comando / terminal.

Descargue el archivo de configuración, así como las gafas y la máscara correspondiente:

 #    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"]) 

Aquí cargamos el archivo de configuración (que puede estar disponible en el futuro como un diccionario Python). Luego cargue las gafas de sol y la máscara.

Si queda algo del script anterior, elimine el directorio temporal y vuelva a crear el directorio temporal vacío. La carpeta temporal contendrá cada cuadro individual de la animación GIF.

Ahora cargue el detector facial de aprendizaje profundo OpenCV en la memoria:

 # 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"]) 

Para hacer esto, llame a cv2.dnn.readNetFromCaffe . El módulo dnn solo está disponible en OpenCV 3.3 o posterior. Un detector de rostros detectará la presencia de rostros en la imagen:


Fig. 7. Operación del detector de rostros usando OpenCV DNN

A continuación, cargue el predictor de hito de cara dlib . Le permitirá localizar estructuras individuales: ojos, cejas, nariz, boca y mentón:


Fig. 8. Los puntos de referencia descubiertos por dlib se superponen en mi cara

Más adelante en este guión extraemos solo el área de los ojos.

Continuando, busquemos la cara:

 #       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) 

En este bloque hacemos lo siguiente:

  • Descargue la image original.
  • Construimos una blob para enviar al detector facial de una red neuronal. Este artículo describe cómo funciona blobFromImage de OpenCV.
  • Realice el procedimiento de detección de rostros.
  • Encontramos a la persona con el valor de probabilidad más alto y lo comparamos con el umbral de probabilidad mínimo aceptable. Si no se cumplen los criterios, simplemente salga del script. De lo contrario, continúe.

Ahora extraeremos la cara y calcularemos los puntos de referencia:

 #   (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] 

Para extraer la cara y encontrar puntos de referencia faciales, hacemos lo siguiente:

  • Extraemos las coordenadas del cuadro delimitador alrededor de la cara.
  • Cree un objeto rectangle en dlib y aplique la localización de caras.
  • Recuperamos las coordenadas (x, y) de leftEyePts y rightEyePts , respectivamente.

Dadas las coordenadas de los ojos, puede calcular dónde y cómo colocar las gafas de sol:

 #       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) 

Primero, calculamos el centro de cada ojo, luego el ángulo entre los centroides. La misma operación se realiza con la alineación horizontal de la cara en el marco .

Ahora puede rotar y cambiar el tamaño de las gafas. Tenga en cuenta que utilizamos la función rotate_bound , no solo rotate , de modo que OpenCV no recorta partes que no son visibles después de la conversión afín.

Las mismas operaciones que se aplicaron a las gafas, se aplican a la máscara. Pero primero debe convertirlo a tonos de gris y binarizar, porque las máscaras siempre son binarias. Luego giramos y redimensionamos la máscara de la misma manera que lo hicimos con los anteojos.

Nota: tenga en cuenta que al cambiar el tamaño de la máscara, usamos interpolación para los puntos vecinos más cercanos, porque la máscara debe tener solo dos valores (0 y 255). Otros métodos de interpolación son más estéticos, pero no adecuados para máscaras. Aquí puede obtener información adicional sobre la interpolación en los puntos vecinos más cercanos.

Los tres bloques de código restantes crean marcos para la animación 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)) 

Las gafas caen desde la parte superior de la imagen. En cada cuadro, se muestran más cerca de la cara hasta que cubren sus ojos. Usando la variable "steps" en el archivo de configuración JSON, generamos coordenadas y para cada cuadro. Para hacer esto, sin mucho esfuerzo, usamos la función linspace de NumPy.

Las líneas con un ligero desplazamiento hacia la izquierda y hacia arriba pueden parecer un poco extrañas, pero son necesarias para garantizar que las gafas cubran los ojos en su conjunto y no solo se muevan hasta el punto donde se encuentra el centro del ojo. Determiné empíricamente porcentajes para calcular el desplazamiento a lo largo de cada eje. La siguiente línea asegura que no haya valores negativos.

Usando la función overlay_image , generamos el marco de output final.

Ahora aplique el texto "TRATE CON EL" usando otra máscara:

  #    ,    #  "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)) 

En el último paso, imponemos el texto, que en realidad es otra imagen.

Decidí usar una imagen porque las capacidades de representación de las fuentes OpenCV son bastante limitadas. Además, quería agregar una sombra y un borde alrededor del texto, que de nuevo OpenCV no sabe cómo.

En el resto de este código, cargamos tanto la imagen como la máscara, y luego realizamos una mezcla alfa para generar el resultado final.

Solo queda guardar cada fotograma en el disco con la creación posterior de animación 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) 

Escribimos el resultado en el disco. Después de generar todos los cuadros, llamamos a la función create_gif para crear el archivo de animación GIF. Recuerde que este es un shell que pasa parámetros a la herramienta de línea de comandos de convert ImageMagick.

Finalmente, elimine el directorio de salida temporal y los archivos de imagen individuales.

Resultados


Ahora la parte divertida: ¡veamos qué creó nuestro generador de memes!

Asegúrese de descargar el código fuente, las imágenes de muestra y los modelos de aprendizaje profundo. Luego abra una terminal y ejecute el siguiente comando:

 $ 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... 


Figura 9. Animación GIF generada con OpenCV e ImageMagick con este script de Python

Aquí puede ver el GIF creado con OpenCV e ImageMagick. Se realizan las siguientes acciones en él:

  1. Detección correcta de mi cara.
  2. Localización de los ojos y cálculo de sus centros.
  3. Las gafas caen correctamente sobre la cara.

Los lectores de mi blog saben que soy un gran nerd en Jurassic Park y a menudo lo mencionan en mis libros, cursos y guías de estudio.

¿No te gusta Jurassic Park ?

Ok, aquí está mi respuesta:

 $ 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. Animación GIF de OpenCV basada en una fotografía de la proyección reciente de Jurassic World 2

Aquí estoy en el espectáculo "Jurassic World: 2" en una camiseta temática, con un vaso de luz y un libro de colección.

Historia divertida:

Hace cinco o seis años, mi esposa y yo visitamos el parque temático Epcot Center en Disney World, Florida.

Decidimos hacer un viaje para alejarnos de los duros inviernos en Connecticut, y necesitábamos desesperadamente la luz del sol.

Desafortunadamente, en Florida llovió todo el tiempo y la temperatura apenas superó los 10 ° C.

Cerca de los jardines canadienses, Trisha me tomó una foto: dice que me veo como un vampiro con piel pálida, ropa oscura y una capucha, en el contexto de los exuberantes jardines detrás:

 $ 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. Usando OpenCV y Python, puedes crear este meme u otro GIF animado

Esa misma tarde, Trisha publicó una foto en las redes sociales, tuve que aguantarla.

Aquellos de ustedes que asistieron a PyImageConf 2018 ( lea la reseña ) saben que siempre estoy abierto a bromas. Aquí hay un ejemplo:

Pregunta: ¿Por qué el gallo cruza la calle?

 $ 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. La cara se reconoce incluso con poco contraste, y OpenCV procesa correctamente la foto y baja las gafas de sol.

Respuesta: No diré la respuesta, aguanta esto.

Finalmente, concluimos la guía de hoy con un buen meme.

Hace unos seis años, mi padre y yo adoptamos un pequeño beagle, Gemma.

Aquí puedes ver a Gemma en mi hombro:

 $ 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 es deliciosa. ¿No te parece? Entonces "¡acéptalo!"

¿No estás de acuerdo con que ella es linda? Tratar con eso.

¿Tiene un error AttributeError?


No te preocupes!

Si viste este error:

 $ 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' 

... entonces solo necesita actualizar el paquete imutils:

 $ pip install --upgrade imutils Collecting imutils ... Successfully installed imutils-0.5.1 

Por qué

Por defecto, imutils.face_utilsutiliza un detector de puntos de referencia de 68 puntos integrado en dlib (como en este artículo). Hay un detector de 5 puntos más rápido , que ahora también funciona con imutils. Recientemente actualicé imutils para admitir ambos detectores (por lo que puede ver un error).

Resumen


En el tutorial de hoy, aprendiste a crear GIF usando OpenCV.

Para que la lección sea divertida, utilizamos OpenCV para generar la animación GIF "Deal With It", un meme popular (y mi favorito) que se encuentra de una forma u otra en casi todos los sitios de redes sociales.

En el proceso, utilizamos la visión por computadora y el aprendizaje profundo para resolver varios problemas prácticos:

  • Identificación de personas
  • Pronosticar puntos de referencia en la cara
  • Identificación de áreas de la cara (en este caso, el ojo)
  • Calcular el ángulo entre los ojos para alinear la cara
  • Crea mezclas transparentes con mezcla alfa

Finalmente, tomamos un conjunto de imágenes generadas y creamos un GIF animado usando OpenCV e ImageMagick.

¡Espero que hayas disfrutado el tutorial de hoy!

Si te gustó, deja un comentario y avísame.

Bueno, si no te gustó, no importa, solo aguanta. ;)

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


All Articles