día 1: Caras con ojos

Este día, vamos a inspeccionar la funciones, y de entre ellas, nos concentraremos en la más importante para nosotros, la función detect_and_draw.

Recordamos que el programa poseía una serie de funciones:

  1. Init: Según el medio por el que vayamos a obtener nuestra captura, inicializa la captura con una captura de la webcam, un vídeo .avi o una imagen .jpg. Si no le pasas ningún argumento, obtiene las imágenes de la webcam, como nosotros deseamos. Finalmente crea una ventana donde mostrará las imágenes con las caras detectadas.
  2. ImageProcess: Si se ha inicializado la captura, entramos en un bucle infinito, en el que pasamos a crear una imagen de esta captura de una determinada anchura y altura. Llamamos al método detect_and_draw al que le pasamos esta imagen, y así sucesivamente hasta que salgamos por pulsación de una tecla.
  3. Detect_and_draw: Este método en un principio hace una serie de operaciones, como son la ecualización, y modificación de las dimensiones de la imagen.Posteriormente, en caso de que cascade, que es una variable que habíamos inicializado en init, haya sido inicializada correctamente (es decir, hayamos cargado el fichero de las caras correctamente, detecta todas las caras que hay en pantalla, y las guarda en un array llamado faces.

También saca por pantalla el tiempo que ha tardado en realizar la detección.

Después, para todas las caras, el método halla su centro y su radio para poder pintar un círculo de un color que depende de la posición respecto a las demás caras en la pantalla, según cómo realice el barrido.

Vemos después las siguientes instrucciones:

if( !nested_cascade ){

cvCircle( img, center, radius, color, 3, 8, 0 );

continue;

Esto nos da a pensar que puede haber otro tipo de detección apilada dentro de la detección de caras, con lo que trabajaremos posteriormente.

En caso de que salga del if por el continue, pasa a analizar la siguiente cara y a pintarle el círculo correspondiente.

Cuando termine con todas las caras, muestra la imagen modificada en la ventana de visualización abierta para ello y libera la imagen después, finalizando ahí el método.

Vamos a pasar ahora a observar en qué consiste lo de los nested_objects de los que hablábamos antes. Efectivamente, viendo el código posterior a la sentencia if, vemos un bucle for, que realiza la misma función que con las caras pero detectando ojos, como indica arriba del todo el fichero similar al de detectar caras, de forma que el fichero que abre el programa para detectar caras es:

const char* cascade_name =
“../../data/haarcascades/haarcascade_frontalface_alt.xml”;


Para abrir ojos es:

const char* nested_cascade_name =
// “../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml”;

Lo descomentamos todo para que funcione, y en el bucle de init, hacemos algo parecido a lo que había hecho conc ascade, pero con nested_cascade, que será para detectar ojos en vez de caras. Así en init tendríamos:

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

if( !cascade )
{
fprintf( stderr, “ERROR: Could not load classifier cascade\n” );
fprintf( stderr,
“Usage: facedetect [–cascade=\”<cascade_path>\”]\n”
”   [–nested-cascade[=\”nested_cascade_path\”]]\n”
”   [–scale[=<*imag scale>\n”
”   [filename|camera_index]\n” );
return -1;


Añadiremos esto:

if( !nested_cascade )
{
fprintf( stderr, “ERROR: Could not load classifier nested_cascade %s\n”, nested_cascade_name);
fprintf( stderr,
“Usage: facedetect [–cascade=\”<cascade_path>\”]\n”
”   [–nested-cascade[=\”nested_cascade_path\”]]\n”
”   [–scale[=<*imag scale>\n”
”   [filename|camera_index]\n” );
return -1;
}

Ahora, podrá pasar a entrar al bucle de los ojos, en caso de detectarlos, porque en el if(!nested_cascade) comentado anteriormente, ya tendrá bien cargado el fichero, y pasará a ejecutar la detección de ojos dentro de cada cara y el bucle for correspondiente.
Ahora tenemos una nueva herramienta, los ojos de las caras son detectados, y pensamos que puede ser una muy buena herramienta para incrementar la robustez del programa. ¿Cómo? Muy sencillo, sólo dibujará las caras que tengan ojos, de tal forma que cuando detecte objetos extraños, será muy difícil que detecte ojos en ellos.

Por tanto las llamadas a cvCircle que lo que hacen es pintar el círculo de las dimensiones especificadas en una imagen, las incluiremos dentro del bucle de los ojos, de tal forma que sólo pintará la cara si ha detectado los ojos de esa cara. Para ello, hemos tenido que cambiar el nombre de las variables del círculo del ojo: radius y center, porque dentro de su bucle vamos a utilizar las variables del círculo de la cara, del mismo nombre. Así quedarían las dos llamadas para pintar los círculos:
cvCircle( img, center, radius, color, 3, 8, 0 )

cvCircle( img, centero,radiuso, color, 3, 8, 0 );

También en el radio del ojo, hemos reducido la escala, para que los ojos pintados sean más pequeños.
Así damos por finalizado este día, en el que hemos conseguido un importante avance para la robustez del programa. Sin embargo, a partir de ahora, probablemente no estemos interesados en dibujar en la imagen círculos, sino en guardar las imágenes y los parámetros de la situación de las caras, para poder detectar el movimiento, e identificar caras cuando se desplacen por la pantalla.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: