Incapaz de detectar pontos de referência faciais usando OpenCV2

Jan 22 2021

Eu desenvolvi um script usando dlibe cv2para desenhar marcos faciais em imagens que têm um rosto naquela imagem. Aqui estão os scripts;

import cv2
import dlib

img_path = 'landmarks.png'
detector = dlib.get_frontal_face_detector()

shape_predictor = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(shape_predictor)


count = 1
ready = True
while ready:
    frame = cv2.imread("demo.jpg")
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = detector(gray)
    for face in faces:
        x1 = face.left()
        y1 = face.top()
        x2 = face.right()
        y2 = face.bottom()
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 3)

        landmarks = predictor(gray, face)

        for n in range(0, 68):
            x = landmarks.part(n).x
            y = landmarks.part(n).y
            cv2.circle(frame, (x, y), 4, (255, 0, 0), -1)

    cv2.imshow("Frame", frame)
    cv2.waitKey(0)
    ready = False

Agora, aqui está o que me deixa louco. Quando tento baixar qualquer uma das imagens (com ou sem máscara) do google para testá-la, este script está funcionando bem. Da mesma forma, você pode ver esses resultados como,

Mas quando tento essas imagens a seguir, não adianta nada.

Fiz algumas pesquisas na Internet, mas não encontrei nada que esteja atendendo ao propósito atual.

Mesmo, eu tentei a combinação de

  • cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
  • eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
  • m_cascade = cv2.CascadeClassifier('haarcascade_mcs_mouth.xml')

Eu também examinei os seguintes links úteis por aí;

  • Face Bounding Box

  • Detectar marcos de rosto no Android (mesmo que não seja o mesmo domínio)

  • Detecção de pontos de referência

  • OpenCV2 Detectar pontos de referência faciais

mas também não está funcionando nessas imagens. CV2 detectormostra uma lista vazia quando eu depuro por meio de um script como;

Eu só quero desenhar pontos de referência fiduciais usando as imagens acima. Qual seria a melhor solução possível, posso passar? Talvez esteja faltando alguma coisa em cv2& Dlib, mas não consigo obter os resultados necessários.

Também encontrei a pontuação de confiança para dlibusar a implementação recomendada de um geek do Stack Overflow , como;

import dlib

detector = dlib.get_frontal_face_detector()

img = dlib.load_rgb_image('demo.jpg')
dets, scores, idx = detector.run(img, 1, -1)
for i, d in enumerate(dets):
    print("Detection {}, score: {}, face_type:{}".format(
        d, scores[i], idx[i]))

Aqui está o resultado de uma pontuação de confiança para a primeira imagem nas imagens fornecidas acima na segunda linha;

Estou ansioso para obter melhores pesquisas de qualquer um dos caras incríveis por aí. Obrigado

Respostas

j2abro Jan 26 2021 at 09:55

Em primeiro lugar, posso tentar ver se você consegue obter as pontuações de confiança do dlib. Não tenho certeza de qual é o limite de confiança, mas talvez sejam detectados rostos que estão abaixo do limite. Do dlib Git Repo , aqui está um exemplo de como obter confiança nas detecções:

if (len(sys.argv[1:]) > 0):
    img = dlib.load_rgb_image(sys.argv[1])
    dets, scores, idx = detector.run(img, 1, -1)
    for i, d in enumerate(dets):
        print("Detection {}, score: {}, face_type:{}".format(
            d, scores[i], idx[i]))

Como alternativa, considere outro detector de rosto, por exemplo, um detector baseado em CNN como este detector de rosto SSD MobileNet . Não usei esse modelo específico, mas usei modelos semelhantes, como o modelo de detector de rosto baseado em TPU do Google, com resultados muito bons.

AliAhmad Jan 26 2021 at 13:15

Baixe o link " shape_predictor_68_face_landmarks.dat ": insira a descrição do link aqui

Código 100% funcional Experimente este:

import cv2
import dlib
import numpy as np

img= cv2.imread('Capture 8.PNG')
gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

p = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(p)
faces = detector(gray)

for face in faces:
  x1=face.left()
  y1=face.top()
  x2=face.right()
  y2=face.bottom()
  cv2.rectangle(img, (x1,y1), (x2,y2),(0,255,0),3)
  landmarks=predictor(gray, face)
  for n in range(0,68):
    x=landmarks.part(n).x
    y=landmarks.part(n).y
    cv2.circle(img, (x, y), 4, (0, 0, 255), -1)

cv2.imshow(img)