Determine la inclinación de la cara usando OpenCV – Python

En este artículo vamos a ver cómo determinar la inclinación de la cara usando OpenCV en Python.

Para lograr esto, usaremos una popular biblioteca de visión por computadora opencv-python . En este programa, con la ayuda de la biblioteca OpenCV, detectaremos caras en una transmisión en vivo desde una cámara web o un archivo de video y, posteriormente, también determinaremos el ángulo según la inclinación de la cara.

Requisitos:

  • Instale OpenCV para Python.
  • Usaremos dos clasificadores XML pre-entrenados para detectar caras y ojos respectivamente. Estos clasificadores se pueden descargar de la biblioteca opencv o simplemente hacer clic en los enlaces a continuación.
  • Clasificador para detección de rostros: haarcascade_frontalface_default.xml
  • Clasificador para detección de ojos: haarcascade_eye.xml

Algoritmo:

  • En primer lugar, detectamos la cara en la transmisión/vídeo de la cámara web utilizando el clasificador Haarcascade mencionado anteriormente para la cara y creamos un cuadro delimitador de color verde a su alrededor.
  • A continuación, detectamos los ojos usando un clasificador Haarcascade similar entrenado en los ojos y creamos un cuadro delimitador de color rojo alrededor de cada ojo.
  • Además de hacer un cuadro alrededor de cada ojo, también identificamos y almacenamos el centro de cada cuadro. Aquí, asumimos que el centro del cuadro delimitador es el mismo que el centro del ojo.
  • Para calcular el ángulo de inclinación supondremos que la línea que une los centros de dos ojos es perpendicular a la cara.
  • Tenemos las coordenadas de dos centros en términos de coordenadas (x,y). El eje x es el eje horizontal y el eje y es el eje vertical.
  • Cuando se dan dos puntos  (x_{1}, y_{1})       &  (x_{2},y_{2})      , el ángulo  \ theta       que forma la línea que une los dos puntos con el eje x se puede obtener de la geometría usando la siguiente expresión:

\theta = \arctan(\frac{x_2 - x_1}{y_2 - y_1})

  • En nuestro caso, se calcula el ángulo que forma la línea que une los centros de dos ojos con la horizontal. El ángulo positivo indica la inclinación hacia la derecha y el ángulo negativo indica la inclinación hacia la izquierda.
  • Proporcionó un margen de error de 10 grados (es decir, si la cara se inclina más de 10 grados en cualquiera de los lados, el programa clasificará como inclinación hacia la derecha o hacia la izquierda).

A continuación se muestra la implementación:

Python

import cv2 as cv
import numpy as np
 
 
# 0 for webcam feed ; add "path to file"
# for detection in video file
capture = cv.VideoCapture(0)
face_cascade = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier("haarcascade_eye.xml")
 
while True:
    ret, frame = capture.read()
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.1, 5)
    x, y, w, h = 0, 0, 0, 0
    for (x, y, w, h) in faces:
        cv.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv.circle(frame, (x + int(w * 0.5), y +
                          int(h * 0.5)), 4, (0, 255, 0), -1)
    eyes = eye_cascade.detectMultiScale(gray[y:(y + h), x:(x + w)], 1.1, 4)
    index = 0
    eye_1 = [None, None, None, None]
    eye_2 = [None, None, None, None]
    for (ex, ey, ew, eh) in eyes:
        if index == 0:
            eye_1 = [ex, ey, ew, eh]
        elif index == 1:
            eye_2 = [ex, ey, ew, eh]
        cv.rectangle(frame[y:(y + h), x:(x + w)], (ex, ey),
                     (ex + ew, ey + eh), (0, 0, 255), 2)
        index = index + 1
    if (eye_1[0] is not None) and (eye_2[0] is not None):
        if eye_1[0] < eye_2[0]:
            left_eye = eye_1
            right_eye = eye_2
        else:
            left_eye = eye_2
            right_eye = eye_1
        left_eye_center = (
            int(left_eye[0] + (left_eye[2] / 2)),
          int(left_eye[1] + (left_eye[3] / 2)))
         
        right_eye_center = (
            int(right_eye[0] + (right_eye[2] / 2)),
          int(right_eye[1] + (right_eye[3] / 2)))
         
        left_eye_x = left_eye_center[0]
        left_eye_y = left_eye_center[1]
        right_eye_x = right_eye_center[0]
        right_eye_y = right_eye_center[1]
 
        delta_x = right_eye_x - left_eye_x
        delta_y = right_eye_y - left_eye_y
         
        # Slope of line formula
        angle = np.arctan(delta_y / delta_x) 
         
        # Converting radians to degrees
        angle = (angle * 180) / np.pi 
 
        # Provided a margin of error of 10 degrees
        # (i.e, if the face tilts more than 10 degrees
        # on either side the program will classify as right or left tilt)
        if angle > 10:
            cv.putText(frame, 'RIGHT TILT :' + str(int(angle))+' degrees',
                       (20, 30), cv.FONT_HERSHEY_SIMPLEX, 1,
                       (0, 0, 0), 2, cv.LINE_4)
        elif angle < -10:
            cv.putText(frame, 'LEFT TILT :' + str(int(angle))+' degrees',
                       (20, 30), cv.FONT_HERSHEY_SIMPLEX, 1,
                       (0, 0, 0), 2, cv.LINE_4)
        else:
            cv.putText(frame, 'STRAIGHT :', (20, 30),
                       cv.FONT_HERSHEY_SIMPLEX, 1,
                       (0, 0, 0), 2, cv.LINE_4)
 
    cv.imshow('Frame', frame)
 
    if cv.waitKey(1) & 0xFF == 27:
        break
capture.release()
cv.destroyAllWindows()

Producción:

Publicación traducida automáticamente

Artículo escrito por nsumanth107 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *