Incapaz de detectar pontos de referência faciais usando OpenCV2
Eu desenvolvi um script usando dlib
e cv2
para 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 detector
mostra 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 dlib
usar 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
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.
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)