martes, 23 de noviembre de 2021

Visión artificial #3 | Detección de rostros con OpenCV y DLib

En este acercamiento práctico a la visión artificial se muestra como, de un modo muy sencillo, podemos hacer correr en nuestros dispositivos unos potentes algoritmos de detección facial. En este caso se emplean las populares librerías open source OpenCV y DLib.

Detección de rostros con OpenCV y DLib

El objetivo es desarrollar un pequeño programa capaz de detectar un rostro o, mejor dicho, un grupo concreto de píxeles dentro del conjunto total de una imagen. Todo este mecanismo de pre-procesado de frames, agrupación de píxeles, etc. está disponible en: Visión artificial #2 | Obtención, caracterización e interpretación de imágenes. Recomiendo echarle un vistazo antes de seguir adelante.

1. Dominio del problema de detección facial

El objetivo es simple: desarrollar un programa capaz de detectar uno o varios rostros dentro de una imagen. Para ello se hará uso de las librerías de computer vision que ya mencioné más arriba: OpenCV y DLib. Estas contienen las funciones necesarias para crear dicho programa. Veámoslo paso a paso.

2. Implementación de los algoritmos de detección facial

Lo primero que tenemos que hacer es definir la función principal rectangle_image_passing(path). Esta será la encargada de gestionar todo el procedimiento. Recibe un parámetro path, que será de tipo string y hará referencia a la ruta en la que tenemos guardada la imagen a analizar.

La función toma la imagen correspondiente y la devuelve en forma de array cuyas posiciones son el código de color RGB de cada píxel. Una vez tenemos la imagen guardada en una variable img necesitamos crear una instancia de la clase fhog_object_detector a través de la función get_frontal_face_detector() que implementa DLib.

Este objeto, que almacenaremos en una variable llamada face_detector, será al que le pasaremos como parámetro dicha imagen y nos devolverá otro objeto de tipo rectangle, que no es más que un array con las posiciones superior izquierda e inferior derecha que corresponden a la región rectangular de la imagen en la que se han detectado uno o varios rostros. Asignaremos este array a otra variable: face_positions.

Recapitulemos, ¿qué tenemos de momento? Hemos analizado una imagen en búsqueda de rostros y hemos almacenado el resultado del análisis en forma de coordenadas. Cada par de coordenadas corresponde a un rostro, por lo tanto, usaremos esta información numérica para dibujar rectángulos sobre los rostros correspondientes y así, de un modo visual, evaluar qué tan preciso ha sido nuestro sencillo programa. 

La función que dibuja el rectángulo se llama rectangle(img, (x1, y1), (x2, y2), color, thikness). Recibe la imagen sobre la que va a pintarlo, las coordenadas, el color y el grosor del rectángulo. Luego solo necesitamos mostrar el resultado en una ventana emergente y voilà.

Ahora bien, de forma anexa he escrito dos funciones más: draw_rectangle(face_positions, img) y message_box(title, text, style). Esta última es solamente para mostrar un mensaje en caso de no haber encontrado ningún rostro. La primera contiene un bucle que dibujará un rectángulo por cada una de las coordenadas que reciba desde face_positions. Funciones separadas por simplicidad y legibilidad.

2.1. Código del programa de detección de rostros

imports

rectangle_image_passing(path)

draw_rectangle(face_positions, img)

message_box(title, text, style)

3. Algunos tests de detección facial

Pasando al programa un par de fotos de mi serie favorita, tenemos los siguientes resultados:

Figura 1. Imagen nítida

Figura 2. Imagen de peor calidad

En la Figura 1 se han detectado todos los rostros mientras que en la segunda no. Esto es por que la nitidez de la imagen es imprescindible para tener una buena base sobre la que aplicar los algoritmos.

Hala, a detectar cosas!

ANEXO 1. Librerías, versiones y entorno de programación

Ambas OpenCV y DLib son librerías de código abierto escritas originalmente en C/C++. Para abstraerse un poco de todas las minuciosidades de sus implementaciones y hacer un uso más sencillo de ellas existe la posibilidad usar wrappers desde otros lenguajes de programación como Python (también existen interfaces para Fortran, Java, JavaScript, Octave y MATLAB).

Versiones del software empleado (x64 bits):

(*) Las versiones de DLib y OpenCV a instalar dependerán de la versión de Python que se tenga previamente instalada y de la arquitectura del procesador (32 o 64 bits).

ANEXO 2. Documentación

Para ahondar más en estas y otras muchísimas funciones visitar:

No hay comentarios:

Publicar un comentario