La detección de caras es uno de los usos que podemos darle a la inteligencia artificial, y hay un variado abanico de opciones para lograrlo. En este post voy a explicar como hacer reconocimiento facial utilizando openCV en un sistema operativo linux y el lenguaje de programación python.

Instalando OpenCV

En cualquier distribución basada en debían, que son mis favoritas, lo primero que tenemos que hacer es instalar algunas dependencias de paquetes:

[compilador] sudo apt-get install build-essential
[dependencias] sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
[opcionales] sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

Las del compilador nos van a servir para compilar e instalar openCV. las dependencias nos servirán para que compile correctamente y las opcionales son para que nuestro software tenga un mejor desempeño.

Ahora procedemos a clonar openCV de su repositorio en github

cd ~/
git clone https://github.com/opencv/opencv.git
cd opencv

ahora adentro del repositorio que clonamos creamos una carpeta que se llame “bin” y nos cambiamos a ella y perparamos las fuentes para ser compiladas:

mkdir bin
cd bin
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..

Finalmente hacemos la clásica make & sudo make install

make
sudo make install

Todo este proceso puede tardar mucho tiempo, así que búsquense algo de tomar ?

Características de Haar

Antes de lanzarse a escribir el código, que por cierto es muy fácil, es bueno que entendamos que es lo que esta pasando en el fondo, y como es que estas mágicas lineas de código logran encerrar en un cuadrado verde caras, ojos, placas de vehículos y otros objetos.

Las características de haar consisten en un algoritmo que encuadra partes de la imagen que estamos analizando en secciones rectangulares. Dichas secciones son luego divididas en varias sub-secciones para compararlas en lo que se denomina una imagen integral. La imagen integral es una representación intermedia de la imagen que en una ubicación dada (x, y) contiene la suma de la intensidad (RGB) todos los pixeles arriba y a la izquierda de ese punto.

En la figura el rectángulo mas grande representa la imagen completa y los recuadros las imágenes integrales que en total hacen un detector de un tamaño fijo (e.g: 24×24). Entonces el valor de la imagen integral en la ubicación 1 es la suma de los pixeles en el rectángulo A, el valor en la ubicación 2 es la suma de los pixeles en A + B, la ubicación 3 es A + C, y la ubicación 4 es A+B+C+D. Entonces la suma de pixeles en D podría ser calculada como 4+1-(2+3).

Y hay 4 formas de dividir estos rectángulos detectores de características.

El calcular estos valores en esas ubicaciones sirve para entrenar un modelo de machine learning, que detecta las características propias de esa sección. Digamos que al reconocer un rostro, la sección de los ojos es mas obscura que la sección del puente de la nariz, o que la sección de la boca es mas obscura que la de las mejías.

Al final de haber entrenado el algoritmo con varios cientos de ejemplos de caras, las características de Haar quedan plasmadas en un modelo listo para ser utilizado por el algoritmo. Y su computo es tan veloz, que es posible realizar reconocimiento facial en tiempo real.

Detectando Caras

Primero que nada debemos obtener el modelo que contiene todas las características de Haar entrenadas para reconocer caras. Afortunadamente para nosotros la buena gente de openCV hizo este modelo publico:

https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalcatface.xml

Ya con esto se hace muy fácil hacer un pequeño script que detecta rostros en lenguaje de programación python

Primero descargamos el archivo en el link, y lo ponemos en el mismo directorio de nuestro script.

import cv2

modelo_cascada = cv2.CascadeClassifier('<a href="https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalcatface.xml" target="_blank" rel="noopener" data-mce-href="https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalcatface.xml">haarcascade_frontalcatface.xml</a>')
imagen_rostro = 'cara.jpeg'

imagen = cv2.imread(imagen_rostro)

rostros = modelo_cascada.detectMultiScale(imagen, 
                                        scaleFactor=1.1, 
                                        minNeighbors=3, 
                                        minSize=(30, 30), 
                                        flags=cv2.cv.CV_HAAR_SCALE_IMAGE)
for (x, y, w, h) in rostros:
	cv2.rectangle(imagen, (x, y), (x + w, y + h), (0, 255, 0), 2)
	cv2.imwrite('cara_detectadas.jpg', imagen)

Esencialmente cargamos la imagen con caras a memoria con cv2.imread, detectamos el rostro con el método detectMultiScale, y finalmente dibujamos el triangulo según las coordenadas que nos devolvió este ultimo método.

Y así el script dibujara un rectángulo al rededor de todas las caras que detecta en la foto.

Si a ustedes les interesa saber mas sobre las características de Haar y los fundamentos matemáticos tras la detección de rostros, les recomiendo que lean la siguiente investigación y su bibliografía.

http://www.merl.com/publications/TR2004-043

Categorized in:

Tagged in:

, , ,