Crie GIFs com o OpenCV



Este tutorial mostra como criar GIFs animados usando OpenCV, Python e ImageMagick. Em seguida, combine esses métodos para criar um gerador de memes com o OpenCV!

Todos nós precisamos rir de vez em quando. E talvez a melhor maneira de encontrar lulza seja com memes. Alguns dos meus favoritos:

  • Caco, o sapo: “Mas não é da minha conta”
  • Gato mal-humorado
  • Falha épica
  • Good guy greg

Mas, para mim, pessoalmente, nenhum desses memes pode ser comparado ao meme "Lidar com ele" ("Lide com ele" ou "Entenda você mesmo"), um exemplo disso é dado no início do artigo.

Geralmente é usado nos seguintes casos:

  1. Como resposta ou objeção a alguém que não aprova algo que você fez / disse ("Lide com isso")
  2. Colocar os óculos como se estivesse saindo e deixando a pessoa sozinha com o problema (“Entenda você mesmo”)

Há alguns anos, li um artigo divertido no blog do autor, que não me lembrava de como gerar esses memes usando a visão computacional. Na semana passada, não consegui encontrar este guia em nenhum lugar; portanto, como blogueiro, especialista em visão computacional e especialista em memes, decidi escrever um tutorial! (A propósito, se você acidentalmente conhece a fonte original, informe-me para que eu possa agradecer ao autor. UPD: Acabei de encontrar o artigo original do blog de Kirk Kaiser, MakeArtWithPython ).

O desenvolvimento de um gerador de memes no OpenCV nos ensinará várias valiosas habilidades práticas, incluindo:

  1. Detecção de Rosto Usando Técnicas de Aprendizado Profundo
  2. Usando a biblioteca dlib para detectar marcos faciais e extrair áreas dos olhos
  3. Como calcular o ângulo de rotação entre os olhos com base nas informações recebidas
  4. E, finalmente, como gerar GIFs animados usando o OpenCV (com uma pequena ajuda do ImageMagick)

Este guia deve ser divertido e divertido - e ao mesmo tempo ensinar habilidades valiosas de programação de visão por computador que são úteis no mundo real.

Criando GIFs com o OpenCV


Na primeira parte do guia, discutiremos as condições e dependências necessárias para este projeto, incluindo a configuração adequada do ambiente de desenvolvimento.

Em seguida, considere a estrutura do projeto / catálogo do nosso gerador de GIF OpenCV.

Assim que entendermos a estrutura do projeto, consideraremos: 1) nosso arquivo de configuração; 2) o script Python responsável pela criação de GIFs com o OpenCV.

Por fim, avaliaremos os resultados do programa no meme popular “Deal With It”.

Pré-requisitos e Dependências



Fig. 1. Usaremos OpenCV, dlib e ImageMagick para criar GIFs

Opencv e dlib


O OpenCV é necessário para determinar as faces no quadro e o processamento básico da imagem. Siga um dos meus guias de instalação do OpenCV se o OpenCV não estiver instalado no sistema.

Usamos o Dlib para detectar pontos de referência faciais, o que nos permite encontrar dois olhos no rosto e colocar óculos de sol. Você pode instalar o dlib usando esta instrução .

Imagemagick


Se você não estiver familiarizado com o ImageMagick , em vão. É uma ferramenta de linha de comando de plataforma cruzada com muitos recursos de processamento de imagem.

Deseja converter PNG / JPG para PDF com um comando? Não tem problema

Existem várias imagens das quais você precisa criar um PDF de várias páginas? Facilmente.

Precisa desenhar polígonos, linhas e outras formas? E é possível.

Que tal classificar cores em lotes ou redimensionar todas as imagens com um comando? Para fazer isso, você não precisa escrever algumas linhas no Python para OpenCV.

O ImageMagick também gera GIFs a partir de qualquer imagem.

Para instalar o ImageMagick no Ubuntu (ou Raspbian), basta usar o apt:

Criando GIFs com o OpenCVShell

$ sudo apt-get install imagemagick 

No macOS, você pode usar o HomeBrew:

 $ brew install imagemagick 

imutils


Na maioria dos artigos, cursos e livros, uso meu conveniente pacote de processamento de imagens imutils . Ele é instalado em um sistema ou ambiente virtual usando pip:

 $ pip install imutils 

Estrutura do projeto



Fig. 2. A estrutura do projeto inclui dois diretórios, um arquivo de configuração e um script Python

Existem dois catálogos em nosso projeto:

  • images/ : exemplos de imagens de entrada para as quais queremos criar um GIF animado. Encontrei algumas imagens comigo, mas fique à vontade para adicionar as suas.
  • assets/ : esta pasta contém nosso detector de rosto, detector de marco de rosto e todas as imagens + máscaras relacionadas. Com esses recursos, colocaremos pontos e texto nas imagens originais da primeira pasta.

Devido ao grande número de parâmetros configuráveis, decidi criar um arquivo de configuração JSON, que: 1) facilitará a edição dos parâmetros; 2) exigirá menos argumentos de linha de comando. Todos os parâmetros de configuração necessários para este projeto estão contidos em config.json .

Considere o conteúdo de config.json e create_gif.py .

Nota Por.: O código do projeto e o manual de 17 páginas sobre visão computacional, aprendizado de máquina e OpenCV são emitidos após o registro (espelho: código fonte , manual ).

Geração GIF com OpenCV


Então, vamos continuar e começar a criar nosso gerador de GIF OpenCV!

Conteúdo do arquivo de configuração JSON


Vamos começar com o arquivo de configuração JSON e depois passar para o script Python.

Abra um novo arquivo config.json e insira os seguintes pares de chave / valor:

Criando GIFs com o 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", 

Esses são os arquivos de modelo de detector de rosto OpenCV no aprendizado profundo .

A última linha é o caminho para o preditor de face dlib.

E agora temos alguns caminhos para os arquivos de imagem:

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

Esses são os caminhos para nossos óculos de sol, texto e máscaras correspondentes, mostrados abaixo.

Em primeiro lugar, óculos escuros e uma máscara:


Fig. 3. Você não gosta de óculos com pixels? Apenas aguente


Fig. 4. Você não entende por que precisa de uma máscara para óculos de sol? Apenas aceite isso - ou leia o restante do artigo para obter a resposta.

E agora nosso texto é "LIDAR COM ELE" e a máscara:


Fig. 5. Você odeia Helvetica Neue Condensed? Lide com isso


Fig. 6: Esta máscara permite desenhar uma borda ao redor do texto. Ah, talvez você não queira, quer uma fronteira? Bem, aguente isso

São necessárias máscaras para sobrepor a imagem correspondente na foto: trataremos disso mais tarde.

Agora defina alguns parâmetros para o gerador de memes:

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

Aqui estão as definições para cada um dos parâmetros:

  • min_confidence : probabilidade mínima de detecção de faces necessária.
  • steps : número de quadros na animação final. Cada "passo" move os óculos de sol da borda superior para o alvo (ou seja, para os olhos).
  • delay : atraso entre quadros em centésimos de segundo.
  • final_delay : atraso do último quadro em centésimos de segundo (útil neste contexto, pois queremos que o texto seja exibido por mais tempo que o restante dos quadros).
  • loop : um valor zero indica que o GIF se repete para sempre; caso contrário, especifique um número inteiro positivo para o número de repetições da animação.
  • temp_dir : o diretório temporário no qual cada um dos quadros será armazenado antes de criar o GIF final.

Memes, GIFs e OpenCV


Criamos o arquivo de configuração JSON, agora vamos para o código real.

Abra um novo arquivo, nomeie como create_gif.py e cole o seguinte 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 

Aqui importamos os pacotes necessários. Em particular, usaremos imutils, dlib e OpenCV. Para instalar essas dependências, consulte a seção Pré-requisitos e Dependências acima.

Agora o script possui os pacotes necessários, então overlay_image definir a função 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 

A função overlay_image impõe um primeiro plano ( fg ) na parte superior da imagem de plano de fundo ( bg ) nas coordenadas das coords ( coordenadas (x, y) ), fgMask transparência alfa sobre a máscara de primeiro plano fgMask .

Para se familiarizar com os conceitos básicos do OpenCV, como trabalhar com máscaras, leia este guia .

Para concluir o processo de mistura, execute a mistura 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") 

Essa implementação de mistura alfa também está disponível no blog LearnOpenCV .

Em essência, converteremos o primeiro plano, o plano de fundo e o canal alfa em números de ponto flutuante no intervalo [0, 1] . Em seguida, executamos a mistura alfa, adicionamos o primeiro plano e o plano de fundo para obter o resultado que retornamos à função de chamada.

Também criaremos uma função auxiliar que permite gerar GIFs a partir de um conjunto de caminhos de imagem usando o ImageMagick e o comando 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) 

A função create_gif pega um conjunto de imagens e as coleta em animações GIF com um atraso especificado entre quadros e loops. O ImageMagick processa tudo isso - simplesmente envolvemos o comando convert em uma função que processa dinamicamente vários parâmetros.

Para ver os argumentos de convert disponíveis, consulte a documentação . Lá você verá quantas funções essa equipe possui!

Especificamente nesta função, nós:

  • Tome imagePaths .
  • Escolha o caminho da última imagem, que terá um atraso separado.
  • Reatribua imagePaths para excluir o último caminho.
  • Montamos um comando com argumentos de linha de comando e instruímos o sistema operacional a convert para criar animações GIF.

Atribua ao script seus próprios argumentos de linha 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()) 

Temos três argumentos de linha de comando que são processados ​​em tempo de execução:

  • --config : caminho para o arquivo de configuração JSON. Revimos o arquivo de configuração na seção anterior.
  • --image : caminho para a imagem de entrada na qual a animação é criada (ou seja, detectar um rosto, adicionar óculos de sol e depois texto).
  • --output : caminho para o GIF resultante.

Cada um desses argumentos é necessário ao executar o script na linha de comando / terminal.

Baixe o arquivo de configuração, os óculos e a máscara correspondente:

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

Aqui, carregamos o arquivo de configuração (que pode estar disponível no futuro como um dicionário Python). Em seguida, coloque os óculos escuros e a máscara.

Se algo restar do script anterior, exclua o diretório temporário e recrie o diretório temporário vazio. A pasta temporária conterá cada quadro individual da animação GIF.

Agora carregue o detector de rosto de aprendizado profundo OpenCV na memória:

 # 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 fazer isso, chame cv2.dnn.readNetFromCaffe . O módulo dnn está disponível apenas no OpenCV 3.3 ou posterior. Um detector de rosto detectará a presença de rostos na imagem:


Fig. 7. Operação do Detector de Rosto Usando o OpenCV DNN

Em seguida, carregue o preditor de ponto de referência dlib face . Permite localizar estruturas individuais: olhos, sobrancelhas, nariz, boca e linha do queixo:


Fig. 8. Os pontos de referência descobertos por dlib estão sobrepostos no meu rosto

Mais adiante neste script, extraímos apenas a área dos olhos.

Seguindo em frente, vamos encontrar o rosto:

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

Neste bloco, fazemos o seguinte:

  • Faça o download da image original.
  • Construímos um blob para enviar ao detector de faces de uma rede neural. Este artigo descreve como o blobFromImage do OpenCV funciona.
  • Execute o procedimento de detecção de rosto.
  • Encontramos a pessoa com o maior valor de probabilidade e o comparamos com o limite mínimo de probabilidade aceitável. Se os critérios não forem atendidos, basta sair do script. Caso contrário, continue.

Agora vamos extrair o rosto e calcular os pontos de referência:

 #   (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 extrair o rosto e encontrar pontos de referência faciais, fazemos o seguinte:

  • Extraímos as coordenadas da caixa delimitadora ao redor da face.
  • Crie um objeto rectangle no dlib e aplique a localização da face.
  • Recuperamos as coordenadas (x, y) de leftEyePts e rightEyePts , respectivamente.

Dadas as coordenadas dos olhos, você pode calcular onde e como colocar os óculos 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) 

Primeiro, calculamos o centro de cada olho, depois o ângulo entre os centróides. A mesma operação é realizada com alinhamento horizontal da face no quadro .

Agora você pode girar e redimensionar os óculos. Observe que usamos a função rotate_bound , não apenas rotate , para que o OpenCV não apare partes que não são visíveis após a conversão afim.

As mesmas operações que foram aplicadas aos óculos se aplicam à máscara. Mas primeiro você precisa convertê-lo em tons de cinza e binarizar, porque as máscaras são sempre binárias. Em seguida, giramos e redimensionamos a máscara da mesma maneira que fizemos com os óculos.

Nota: observe que, ao redimensionar a máscara, usamos interpolação para os pontos vizinhos mais próximos, porque a máscara deve ter apenas dois valores (0 e 255). Outros métodos de interpolação são mais estéticos, mas não são adequados para máscaras. Aqui você pode obter informações adicionais sobre interpolação nos pontos vizinhos mais próximos.

Os três blocos restantes de código criam quadros para a animação 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)) 

Os óculos caem da parte superior da imagem. Em cada quadro, eles são exibidos mais perto do rosto até cobrir os olhos. Usando a variável "steps" no arquivo de configuração JSON, geramos coordenadas y para cada quadro. Para fazer isso, sem muito esforço, usamos a função linspace do NumPy.

As linhas com um pequeno deslocamento para a esquerda e para cima podem parecer um pouco estranhas, mas são necessárias para garantir que os óculos cubram os olhos como um todo, e não apenas se movam para o ponto em que o centro do olho está. Eu determinei empiricamente porcentagens para calcular o deslocamento ao longo de cada eixo. A próxima linha não garante valores negativos.

Usando a função overlay_image , geramos o quadro de output final.

Agora aplique o texto “LIGUE COM ELE” usando outra 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)) 

No último passo, impomos o texto, que na realidade é outra imagem.

Decidi usar uma imagem porque os recursos de renderização das fontes OpenCV são bastante limitados. Além disso, eu queria adicionar uma sombra e uma borda ao redor do texto, que novamente o OpenCV não sabe.

No restante deste código, carregamos a imagem e a máscara e, em seguida, executamos a mistura alfa para gerar o resultado final.

Resta apenas salvar cada quadro em disco com a criação subsequente da animação 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) 

Escrevemos o resultado no disco. Após gerar todos os quadros, chamamos a função create_gif para criar o arquivo de animação GIF. Lembre-se de que este é um shell que transmite parâmetros para a ferramenta de linha de comando convert ImageMagick.

Por fim, exclua o diretório de saída temporário e os arquivos de imagem individuais.

Resultados


Agora a parte divertida: vamos ver o que nosso gerador de memes criou!

Certifique-se de baixar o código-fonte, imagens de exemplo e modelos de aprendizado profundo. Em seguida, abra um terminal e execute o seguinte 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. Animação GIF gerada com OpenCV e ImageMagick com este script Python

Aqui você pode ver o GIF criado usando o OpenCV e o ImageMagick. As seguintes ações são executadas nele:

  1. Detecção correta do meu rosto.
  2. Localização dos olhos e cálculo de seus centros.
  3. Os óculos caem corretamente no rosto.

Os leitores do meu blog sabem que sou um grande nerd no Jurassic Park e frequentemente o menciono em meus livros, cursos e guias de estudo.

Não gosta de Jurassic Park ?

Ok, aqui está a minha resposta:

 $ 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. Animação em GIF OpenCV baseada em uma fotografia da recente exibição de Jurassic World 2

Aqui estou no show "Jurassic World: 2" em uma camiseta temática, com um copo de luz e um livro de coleção.

História divertida:

Cinco ou seis anos atrás, eu e minha esposa visitamos o parque temático do Epcot Center na Disney World, na Flórida.

Decidimos fazer uma viagem para fugir dos invernos rigorosos de Connecticut e precisávamos desesperadamente da luz do sol.

Infelizmente, na Flórida, choveu o tempo todo e a temperatura mal ultrapassou 10 ° C.

Perto dos jardins canadenses, Trisha tirou uma foto minha: ela diz que eu pareço um vampiro de pele clara, roupas escuras e capuz, contra o fundo dos jardins luxuriantes atrá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 e Python, você pode criar esse meme ou outro GIF animado

Naquela mesma noite, Trisha publicou uma foto nas redes sociais - eu tive que aturar isso.

Aqueles de vocês que participaram do PyImageConf 2018 ( leia a resenha ) sabem que estou sempre aberto a brincadeiras. Aqui está um exemplo:

Pergunta: Por que o galo atravessa a estrada?

 $ 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. O rosto é reconhecido mesmo com baixo contraste, e o OpenCV processa corretamente a foto e abaixa os óculos de sol.

Resposta: Não direi a resposta - aguente isso.

Finalmente, concluímos o guia de hoje com um bom meme.

Cerca de seis anos atrás, meu pai e eu adotamos um pequeno beagle, Gemma.

Aqui você pode ver Gemma no meu ombro:

 $ 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 é deliciosa. Você não acha? Então "aceite isso!"

Não concorda que ela é fofa? Lide com isso.

Possui um erro no AttributeError?


Não se preocupe!

Se você viu este erro:

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

... então você só precisa atualizar o pacote imutils:

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

Porque

Por padrão, ele imutils.face_utilsusa um detector de ponto de referência de 68 pontos embutido no dlib (como neste artigo). Existe um detector de 5 pontos mais rápido , que agora também funciona com imutils. Atualizei recentemente o imutils para suportar os dois detectores (para que você possa ver um erro).

Sumário


No tutorial de hoje, você aprendeu como criar GIFs usando o OpenCV.

Para tornar a lição divertida, usamos o OpenCV para gerar a animação GIF “Deal With It”, um meme popular (e o meu favorito) encontrado de uma forma ou de outra em quase todos os sites de redes sociais.

No processo, usamos visão computacional e aprendizado profundo para resolver vários problemas práticos:

  • Identificação de pessoas
  • Previsão de pontos de referência na face
  • Identificação de áreas da face (neste caso, o olho)
  • Cálculo do ângulo entre os olhos para alinhar o rosto
  • Crie misturas transparentes com a mistura alfa

Finalmente, pegamos um conjunto de imagens geradas e criamos um GIF animado usando o OpenCV e o ImageMagick.

Espero que tenham gostado do tutorial de hoje!

Se você gostou, deixe um comentário e me avise.

Bem, se você não gostou, não importa, apenas supere. ;)

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


All Articles