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 & , el ángulo 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:
- 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