domingo, 26 de septiembre de 2010

SOLUCIÓN RETO IV: SEGMENTACIÓN DE CARAS EN UNA IMAGEN

Muy buenas a todos, al final después de muchas búsquedas, he encontrado la solución a este reto.   La solución es más fácil de lo que yo pensaba, ya que ya estaba hecha en OpenCV.  Gracias al libro "Learnin OpenCV" de Gary Bradski y Adrian Kaehler, de la editorial O'reilly, lo he encontrado.

En OpenCV existe una función llamada cvHaarDetectObjects, que reconoce objetos utilizando el clasificador de Viola-Jones.  

  1. Usa las características de entrada Haar-Like:  un umbral aplicando sumas y restas de regiones rectangulares de la imagen.
  2. Es una técnica de integración de imagen que permite una rápida del valor de la región rectangular o regiones giradas 45º.  Esta estructura de datos es utilizada para acelerar los cálculos de las características de las entradas.
  3. Se utiliza para crear una clasificación de las características por alta detección y débil rechazo.
  4. Esta organizado en un débil clasificador de nodos en una cascada de rechazos. En otras palabras, en el primer clasificador seleccionamos la mejor región detectada que contiene el objeto, permitiendo errores en la detección, en el siguiente nodo la segundo mejor detección.  En un modo de test un objeto es detectado solo si ha superado toda la cascada de nodos.
Para utilizar esta función necesitamos entrenar la función cvHaarDetectObjects, en este reto no la hemos entrenado, lo dejamos para retos posteriores, ya que dentro del directorio data, de openCV encontramos el archivo haarcascade_frontalface_alt.xml  que es el que he utilizado.  Si es que al final OpenCV lo tiene todo resuelto, je je je.

A continuación dejo el código que he generado.

#include "cv.h"
#include "highgui.h"

#include <iostream>
#include <cstdio>



void Deteccion_y_dibujo( IplImage* imagen,CvHaarClassifierCascade* cascade,CvMemStorage* storage, double escala);





void main()
{
     CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "haarcascade_frontalface_alt.xml",0, 0, 0 );
     CvMemStorage* storage = cvCreateMemStorage(0);
     IplImage* imagen = cvLoadImage("HPIM1403.jpg");
     IplImage* imagenPequeña =cvCreateImage(cvSize((int)((imagen->width*25)/100) , (int)((imagen->height*25)/100) ),imagen->depth, imagen->nChannels );
     cvResize(imagen,imagenPequeña,CV_INTER_NN);
     Deteccion_y_dibujo(imagenPequeña, cascade, storage,1 );
     //Creamos la ventana
     cvNamedWindow( "Imagen", CV_WINDOW_AUTOSIZE );
     //Dibujamos la imagen
     cvShowImage( "Imagen", imagenPequeña);
     
     cvWaitKey(0);
     cvReleaseImage(&imagen);

  
}

void Deteccion_y_dibujo( IplImage* imagen,CvHaarClassifierCascade* cascade,CvMemStorage* storage, double escala  )
{
     static CvScalar colores[] = {
        {{0,0,255}}, {{0,128,255}},{{0,255,255}},{{0,255,0}},
        {{255,128,0}},{{255,255,0}},{{255,0,0}}, {{255,0,255}}};//Colores para dibujar
     
     //Preparación de la imagen
     IplImage* gris = cvCreateImage( cvSize(imagen->width,imagen->height), 8, 1 );
     IplImage* Imagen_Pequeña = cvCreateImage(
                cvSize( cvRound(imagen->width/escala), cvRound(imagen->height/escala)), 8, 1);
     cvCvtColor( imagen, gris, CV_BGR2GRAY );
     cvResize( gris, Imagen_Pequeña, CV_INTER_LINEAR );
     cvEqualizeHist( Imagen_Pequeña, Imagen_Pequeña );
     
     //Detección si las hay
     cvClearMemStorage( storage );
     CvSeq* objects = cvHaarDetectObjects(
            Imagen_Pequeña,
            cascade,
            storage,
            1.1,
            2,
            0 /*CV_HAAR_DO_CANNY_PRUNING*/,
            cvSize(30, 30));
     //Dibujamos cuadros al rededor de los objetos
     for(int i = 0; i < (objects ? objects->total : 0); i++ ) {
            CvRect* r = (CvRect*)cvGetSeqElem( objects, i );
            cvRectangle(
            imagen,
            cvPoint(r->x,r->y),
            cvPoint(r->x+r->width,r->y+r->height),
            colores[i%8]
            );
     }
     cvReleaseImage( &gris );
     cvReleaseImage( &Imagen_Pequeña );
}

Aquí pongo unas fotografías en las que muestro los resultados.


Bueno, en los próximos días publicare el siguiente reto.  Espero que no me cueste tanto como este je je je.

1 comentario:

  1. saludos, hermano que gusto encontrar este post,tengo un proyecto de la universidad, y es primero educar un sistema para que pueda comparar fotos y reconocer una foto en un grupo y acertar..
    espero sigas publicando y si puede ayudarme me puede escribir a rafaelvtaveras@hotmail.com gracias.. de hecho ya me estas ayudando.

    ResponderEliminar