Detección de rostros con MEDIAPIPE ? | Python – MediaPipe – OpenCV

Por Administrador

En el anterior tutorial vimos una de las soluciones que nos provee MediaPipe para la detección de las manos y handlandmarks en Python. En este tutorial estaremos explorando otra de sus soluciones: MediaPipe Face Detection.

CONTENIDO:

  • MediaPipe Face Detection
    • Datos de salida que obtenemos al usar MediaPipe Face Detection
    • Opciones de configuración
    • ¡Vamos con la programación!
      • Detección de rostros con MediaPipe, en imágenes
      • Detección de rostros con MediaPipe, en videos
    • Referencias

MediaPipe Face Detection

Figura 1: Ejemplo del uso de MediaPipe para la detección de rostros.

Según nos relata la documentación de MediPipe, Media Pipe FaceDetection es una solución de detección facial ultrarápida, que además produce coordenadas de 6 puntos claves en el rostro detectado, que soporta múltiples rostros. 

Figura 2: Ejemplo del uso de MediaPipe para la detección de múltiples rostros.

Esta solución está basada en BlazeFace que es un detector de rostros liviano, de buen rendimiento diseñado para inferencias de GPU móviles. 

Entonces este detector aparte de rápido también es preciso, el cual podemos emplear como punto de partida para tareas en las que se necesite obtener esta región de la imagen. 

Datos de salida que obtenemos al usar MediaPipe Face Detection

Cuando usemos esta solución, veremos que tenemos las coordenadas de un cuadro delimitador que nos ayudará a rodear el rostro, y a más de ello también tendremos 6 puntos de referencia o puntos clave, estos se ubicarán en: 

  • 0. Centro del ojo derecho 
  • 1. Centro del ojo izquierdo 
  • 2. Punta de la nariz 
  • 3. Centro de la boca 
  • 4. Trago de la oreja derecha 
  • 5. Trago de la oreja izquierda 

Figura 3: 6 puntos de referencia y sus nombres asociados. Su documentación la puedes encontrar aquí: https://github.com/google/mediapipe/blob/master/mediapipe/python/solutions/face_detection.py

Si tú al igual que yo, no estás familiarizado con el término trago, y te preguntabas en qué parte de nuestra oreja esta, pues según  wikipedia, este es el trago. 

Opciones de Configuración

MIN_DETECTION_CONFIDENCE (POR DEFECTO 0.5) 

Valor mínimo de confianza del modelo de detección de rostros, para que la detección sea considerada como exitosa. Sus valores comprenden de 0 a 1.

Ahora que hemos visto brevemente esta solución pasaremos al código.

¡Vamos con la programación!

Detección de rostros con MediaPipe, en imágenes

import cv2
import mediapipe as mp

mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils

with mp_face_detection.FaceDetection(
    min_detection_confidence=0.5) as face_detection:
    image = cv2.imread("imagen_de_entrada.extension")
    height, width, _ = image.shape
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = face_detection.process(image_rgb)

    print("Detections:", results.detections)
    
    if results.detections is not None:
        for detection in results.detections:
            # Bounding Box
            print(int(detection.location_data.relative_bounding_box.xmin * width))
            xmin = int(detection.location_data.relative_bounding_box.xmin * width)
            ymin = int(detection.location_data.relative_bounding_box.ymin * height)
            w = int(detection.location_data.relative_bounding_box.width * width)
            h = int(detection.location_data.relative_bounding_box.height * height)
            cv2.rectangle(image, (xmin, ymin), (xmin + w, ymin + h), (0, 255, 0), 15)

            # Ojo derecho
            x_RE = int(detection.location_data.relative_keypoints[0].x * width)
            y_RE = int(detection.location_data.relative_keypoints[0].y * height)
            cv2.circle(image, (x_RE, y_RE), 3, (0, 0, 255), 25)

            # Ojo izquierdo
            x_LE = int(detection.location_data.relative_keypoints[1].x * width)
            y_LE = int(detection.location_data.relative_keypoints[1].y * height)
            cv2.circle(image, (x_LE, y_LE), 3, (255, 0, 255), 25)

            # Punta de la nariz
            x_NT = int(detection.location_data.relative_keypoints[2].x * width)
            y_NT = int(detection.location_data.relative_keypoints[2].y * height)
            cv2.circle(image, (x_NT, y_NT), 3, (255, 0, 0), 25)

            # Centro de la boca
            x_MC = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.MOUTH_CENTER).x * width)
            y_MC = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.MOUTH_CENTER).y * height)
            cv2.circle(image, (x_MC, y_MC), 3, (0, 255, 0), 25)

            # Trago de la oreja derecha
            x_RET = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.RIGHT_EAR_TRAGION).x * width)
            y_RET = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.RIGHT_EAR_TRAGION).y * height)
            cv2.circle(image, (x_RET, y_RET), 3, (0, 255, 255), 25)

            # Trago de la oreja izquierda
            x_LET = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.LEFT_EAR_TRAGION).x * width)
            y_LET = int(mp_face_detection.get_key_point(detection, mp_face_detection.FaceKeyPoint.LEFT_EAR_TRAGION).y * height)
            cv2.circle(image, (x_LET, y_LET), 3, (255, 255, 0), 25)
    '''
    # Dibujar los resultados con MediaPipe
    if results.detections is not None:
        for detection in results.detections:
            mp_drawing.draw_detection(image, detection,
            mp_drawing.DrawingSpec(color=(255, 0, 255), thickness=3, circle_radius=3),
            mp_drawing.DrawingSpec(color=(0, 255, 255), thickness=7))
    '''
    cv2.imshow("Image", image)
    cv2.waitKey(0)
cv2.destroyAllWindows()

NOTA: Para más detalles sobre la programación, por favor dale un vistazo al videotutorial.

Detección de rostros con MediaPipe, en video

import cv2
import mediapipe as mp
import imutils
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
#cap = cv2.VideoCapture("video.mp4")

with mp_face_detection.FaceDetection(
    min_detection_confidence=0.5) as face_detection:

    while True:
        ret, frame = cap.read()
        if ret == False:
            break
        frame = imutils.resize(frame, width=720)
        frame = cv2.flip(frame, 1)
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)		

        results = face_detection.process(frame_rgb)

        if results.detections is not None:
            for detection in results.detections:
                mp_drawing.draw_detection(frame, detection,
                    mp_drawing.DrawingSpec(color=(0, 255, 255), circle_radius=2),
                    mp_drawing.DrawingSpec(color=(255, 0, 255)))

        cv2.imshow("Frame", frame)
        k = cv2.waitKey(1) & 0xFF
        if k == 27:
            break
cap.release()
cv2.destroyAllWindows()

Referencias