No se pueden detectar puntos de referencia faciales usando OpenCV2

Jan 22 2021

He desarrollado un guión usando dliby cv2para dibujar puntos de referencia faciales en imágenes que tienen una cara en esa imagen. Aquí están los guiones;

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

Ahora, aquí lo que me vuelve loco. Cuando intento descargar cualquiera de las imágenes (con o sin máscara) de Google para probarlo, este script funciona bien. Asimismo, puede ver estos resultados como,

Pero cuando pruebo estas imágenes siguientes, no hace nada.

He realizado un par de búsquedas en Internet, pero no he encontrado nada que sirva para el propósito actual.

Incluso, he probado la combinación de

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

También he examinado los siguientes enlaces útiles que existen;

  • Caja delimitadora de caras

  • Detectar marcas faciales en Android (incluso no en el mismo dominio)

  • Detección de puntos de referencia

  • OpenCV2 Detecta marcas faciales

pero tampoco funciona con estas imágenes. CV2 detectormuestra una lista vacía cuando depuro a través de un script como;

Solo quiero dibujar puntos de referencia fiduciales usando las imágenes de arriba. ¿Cuál sería la mejor solución posible por la que puedo pasar? Tal vez, me falta algo en cv2& Dlib, pero no puedo obtener los resultados requeridos.

También encontré el puntaje de confianza para dlibusar la implementación recomendada de un geek de 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]))

Aquí está el resultado de una puntuación de confianza para la primera imagen en las imágenes dadas arriba en la segunda fila;

Espero obtener una mejor investigación de cualquiera de los chicos geniales que hay. Gracias

Respuestas

j2abro Jan 26 2021 at 09:55

Primero, podría intentar ver si puede obtener puntajes de confianza de dlib. No estoy seguro de cuál es el umbral de confianza, pero tal vez se detecten rostros que están por debajo del límite. Del dlib Git Repo , aquí hay un ejemplo de cómo obtener confianza de las detecciones:

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

Alternativamente, considere otro detector facial, por ejemplo, un detector basado en CNN como este detector facial MobileNet SSD . No he usado este modelo en particular, pero he usado modelos similares, como el modelo de detector facial basado en TPU de Google aquí con muy buenos resultados.

AliAhmad Jan 26 2021 at 13:15

Descargar el enlace " shape_predictor_68_face_landmarks.dat ": introduzca la descripción del enlace aquí

Código 100% funcional Prueba 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)