Python – Detección de rostros con OpenCV

Con Python 3 y OpenCV para la detección de rostros es muy sencilla, se hace con muy pocas líneas de código.

Necesitas desde luego, tener instalado Python 3.  En este ejemplo descargamos la última versión disponible para Windows directamente de la página.

https://www.python.org/downloads/

Instala Python en un ruta que recuerdes.

Como IDE para editar y compilar usaremos PyCharm Community de JetBrains.

https://www.jetbrains.com/pycharm/download/

Descargar OpenCV

Descargaremos OpenCV desde PyCharm, pero es necesario descargar OpenCV e instalar la versión para Windows, ya que necesitaremos los archivos HAARs que vienen como parte del paquete de archivos de datos para reconocer rostros, ojos y otras cosas bastante útiles.  Después de instalar el archivo ejecutable de OpenCV recuerda la ruta, la usaremos más tarde.

http://opencv.org/downloads.html

python_opencv3_pycharm_02

Crear un proyecto nuevo en PyCharm

Una vez instalado PyCharm, crea un nuevo proyecto.

Al crear el proyecto PyCharm solicitará la ruta del python que instalaste anteriormente.

Descargar e instalar OpenCV desde PyCharm

En las opciones de menú.  En File>Settings

Agrega un paquete nuevo.

Busca y selecciona opencv-python y especifica la versión 3.1 o superior. Después da click en instalar.

No deberías tener problemas para instalar este paquete.

Ahora el código

El código es muy sencillo, solo tienes que crear una archivo de python con el nombre que desees y usar las siguientes líneas:

import cv2

face_cascade = cv2.CascadeClassifier(
    'C:/Users/decodigo/opencv-3.4.6/data/haarcascades/haarcascade_frontalface_default.xml')
if face_cascade.empty(): raise Exception("¿Está seguro que es la ruta correcta?")

eye_cascade = cv2.CascadeClassifier('C:/Users/decodigo/opencv-3.4.6/data/haarcascades//haarcascade_eye.xml')
if eye_cascade.empty(): raise Exception("¿Está seguro que es la ruta correcta?")

video = cv2.VideoCapture(0)
while video.isOpened():
    ret, frame = video.read()
    if frame is not None:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = frame[y:y + h, x:x + w]
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex, ey, ew, eh) in eyes:
                cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
        cv2.imshow('Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video.release()
cv2.destroyAllWindows()

Con las primeras líneas buscamos los archivos HAARs que nos permiten detectar ojos y rostros en OpenCV.

face_cascade = cv2.CascadeClassifier(
    'C:/Users/decodigo/opencv-3.4.6/data/haarcascades/haarcascade_frontalface_default.xml')
if face_cascade.empty(): raise Exception("¿Está seguro que es la ruta correcta?")

eye_cascade = cv2.CascadeClassifier('C:/Users/decodigo/opencv-3.4.6/data/haarcascades//haarcascade_eye.xml')
if eye_cascade.empty(): raise Exception("¿Está seguro que es la ruta correcta?")

Después de eso tomamos el control de la webcam.  Recuerda que si tienes más de una cámara conectada (las laptops vienen con una incluida), debes jugar un poco con los índices para obtener la señal de la cámara que deseas.

video = cv2.VideoCapture(0)

Obtenemos la información de cada frame recibido de la webcam. Hacemos una copia en escala de grises y con la ayuda de la función face_cascade.detectMultiScale(gray, 1.3, 5) obtenemos una lista de todos los rostros encontrados en el frame.

En el ciclo for damos tratamiento a cada rostro encontrado.  Se dibuja un rectángulo y se obtiene una copia del area donde se ha detectado un rostro para después hacer la búsqueda de los ojos.

cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = frame[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(roi_gray)

Para cada ojo se da un tratamiento similar al que hicimos cuando detectamos un rostro en nuevo ciclo for anidado.

Finalmente, mostramos el resultado de cada frame y su tratamiento en una ventana.

cv2.imshow('Video', frame)

Quizá notaste que todo el bloque de código principal se encuentra en un ciclo while que se mantiene activo mientras la señal video está abierta. Este ciclo terminará cuando pulsemos la tecla «q«.

if cv2.waitKey(1) & 0xFF == ord('q'):
  break

Al terminar el ciclo la ventana donde mostramos el video cerrará.

  video.release()
  cv2.destroyAllWindows()

Como puedes ver se trata de un ejemplo muy sencillo. Sólo recuerda cambiar la ruta de los archivos HAAR y usar la correcta dependiendo de donde hayas instalado OpenCV al inicio.  El resultado será algo como la imagen siguiente, donde hay un rostro se dibuja un rectángulo azul, y dentro del mismo se dibuja otro más por cada ojo detectado.  Desde luego el método no es perfecto, pero seguro que puede ser util como primer acercamiento a OpenCV.

Esperamos que disfrutes el ejemplo.

15 thoughts on “Python – Detección de rostros con OpenCV”

        1. Hola, algo tarde pero te comento que lo solucioné a ese error quitando el & 0xFF .
          if cv2.waitkey(1) == ord(‘q’): un dato es que si lo pones con 0 el waitkey te bota capturas que cambian cuando presionas otra tecla que no sea la ‘q’ para cortar el ciclo.
          if cv2.waitkey(0) & == ord(‘q’):

  1. hola me arroja este error,saludos

    File «C:/Users/xxx/Desktop/open CV test.py», line 23
    if cv2.waitKey(1) & 0xFF == ord(‘q’):
    ^
    SyntaxError: invalid syntax

    Process finished with exit code 1

  2. También me causaba error en línea 23, para corregir quiten esto: amp;
    y funciona muy bien. La ruta es de donde guaradron opencv, por ejemplo en mi caso es:

    face_cascade = cv2.CascadeClassifier(
    ‘C:/Users/maria/Downloads/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml’)

  3. Hola, muy util tu ejemplo, me sirvio para terminar de comprender los haar***.xml, ya que el ejemplo de la documentacióon de opencv me daba un error de empty sobre faceCascade. Si quisiera consultarte por la constante 0xFF, que significa o a que hace referencia. Desde ya muchas gracias!

    1. Que tal Nelson, es una línea algo confusa en realidad.

      La respuesta es la siguiente:

      cv2.waitKey(1) & 0xFF == ord(‘q’)

      1.- cv2.waitKey(1) devuelve un entero de 32 bits correspondiente a la tecla presionada.

      2.- & 0xFF aplica una máscara al valor devuelto anteriormente, establece los 24 bits a la izquierda en cero, porque ord() devuelve un valor entre 0 y 255, ya que los valores del teclado tienen un conjunto de caracteres limitado.

      3.- Una vez que la máscara es aplicada, es posible comprobar si el valor capturado es igual a lo que devuelve la funcion ord(‘q’).

      En resumen, la operación & 0xFF te permite ajustar los valores para poder compararlos.

Deja una respuesta

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