La solución a este reto es muy similar a la del reto anterior, seguiremos utilizando la función cvHaarDetectObjects de la misma manera que en el reto anterior. La diferencia es que en este utilizamos una cámara, o sea que estamos reconociendo las caras en un montón de fotografías, una detrás de otra. Esta función devuelve una secuencia, que es donde se encuentran las caras, esta secuencia es del tipo CvSeq, que es una estructura definida de este tipo:
typedef struct CvSeq {
int flags; // misceláneo de banderas
int header_size; // Tamaño y secuencia de la cabecera
CvSeq* h_prev; // secuencia previa
CvSeq* h_next; // secuencia siguiente
CvSeq* v_prev; // Previsión de las secuencia 2n
CvSeq* v_next // Previsión de la secuancia 2n siguiente
int total; // Número total de elementos
int elem_size; // Tamaño de la secuencia en byte
char* block_max; // Máximo contorno en el último bloquie
char* ptr; // Puntero de escritura actual
int delta_elems; // Cuantos punteros asignados cuando la secuencia crece
CvMemStorage* storage; //Cuando la secuencia es almacenada
CvSeqBlock* free_blocks; // Lista libre de bloques
CvSeqBlock* first; // Puntero al primer elemnto de bloque
}
int flags; // misceláneo de banderas
int header_size; // Tamaño y secuencia de la cabecera
CvSeq* h_prev; // secuencia previa
CvSeq* h_next; // secuencia siguiente
CvSeq* v_prev; // Previsión de las secuencia 2n
CvSeq* v_next // Previsión de la secuancia 2n siguiente
int total; // Número total de elementos
int elem_size; // Tamaño de la secuencia en byte
char* block_max; // Máximo contorno en el último bloquie
char* ptr; // Puntero de escritura actual
int delta_elems; // Cuantos punteros asignados cuando la secuencia crece
CvMemStorage* storage; //Cuando la secuencia es almacenada
CvSeqBlock* free_blocks; // Lista libre de bloques
CvSeqBlock* first; // Puntero al primer elemnto de bloque
}
Los parámetros de entrada de esta función son los siguientes; la imagen en tonalidad de grises, un puntero a un dato de tipo CvHaarClassifierCascade* que no es nada más que el archivo donde están los parámetros de reconocimiento, un parámetro del tip CvMemStorage* que es una especie de almacén, más adelante explicaré este elemento, cuando lo entienda mejor je je je, el factor de escala, el número de vecinos, unas banderas y el tamaño mínimo.
Lo que hace esta función ya lo esplique un poco por encima en el reto 4, tampoco vamos a entrar en muchos detalles, hay mucha más información en el libro learning openCV, lo malo que esta en ingles, pero es muy simple de leer.
Como siempre os dejo mi código, más adelante iremos profundizando un poco más. Cuando vaya yo aprendiendo, je je je.
#include "highgui.h"
#include <iostream>
#include <cstdio>
void Deteccion_y_dibujo( IplImage* imagen,IplImage* gris,CvHaarClassifierCascade* cascade,CvMemStorage* storage);
void main()
{
double t;
bool Primera= true;
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "haarcascade_frontalface_alt.xml",0, 0, 0 );
CvMemStorage* storage = cvCreateMemStorage(0);
//Creamos la ventana
cvNamedWindow( "Imagen", CV_WINDOW_AUTOSIZE );
//Capturamos la cámara
CvCapture* capture= cvCreateCameraCapture(0);
assert( capture != NULL );
IplImage* Frame;
IplImage* gris
while(1)
{
Frame=cvQueryFrame(capture); //Capturamos la primera imagen
if(!Frame) break; //Si no hay frame salimos
if (Primera)
{
gris = cvCreateImage( cvSize(Frame->width,Frame->height), 8, 1 );
Primera= false;
}
//Capturamos el tiempo inicial
t = (double)cvGetTickCount();
Deteccion_y_dibujo(Frame,gris, cascade, storage);
//Capturamos el tiempo final y le restamos el inicial
t = (double)cvGetTickCount() - t;
//Visualizamos el tiempo
printf( "Tiempo deteccion = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
//Dibujamos la imagen
cvShowImage( "Imagen", Frame);
char c = cvWaitKey(33);
if(c==27) break;
}
cvReleaseImage(&Frame);
cvReleaseImage( &gris );
}
void Deteccion_y_dibujo( IplImage* imagen,IplImage* gris,CvHaarClassifierCascade* cascade,CvMemStorage* storage )
{
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
cvCvtColor( imagen, gris, CV_BGR2GRAY );
cvEqualizeHist( gris, gris );
//Detección si las hay
cvClearMemStorage( storage );
CvSeq* objects = cvHaarDetectObjects(
gris,
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],
2
);
}
}
También os dejo un video.
No hay comentarios:
Publicar un comentario