recorrer_y_crear_video_fondo_contornos

=Ejemplo de como recorrer video, como crear video, como estimar fondo y primer plano y como trabajar con contornos= Nota: solo funciona en Opencv 1.0 para otros mire los comentarios sobre el código fuente

code format="c" /* Autores: Francisco Calderón - Germán Urrego si va a usar este programa como referencia por favor referenciar el trabajo de grado de pregrado titulado: Conteo automático de vehículos Pontificia universidad javeriana Urrego. G, Calderon. F Noviembre de 2008 http://opencvjaveriana.wikispaces.com/conteo_automatico_de_vehiculos bajo la licencia: http://creativecommons.org/licenses/by-nc-sa/2.5/co/
 * 1) include "stdafx.h"
 * 2) include "cv.h"
 * 3) include "cvaux.h"
 * 4) include "highgui.h"
 * 5) include "cxcore.h"
 * 6) include 
 * 7) include 
 * 1) include 

int main(int argc, char** argv) {   /*variables generales y de uso temporal*/ CvRect bndRect = cvRect(0,0,0,0);//para un ejemplo descomente acá y donde se usa mas abajo CvScalar colorint = CV_RGB(150,80,255); CvScalar colorext = CV_RGB( 50,255,120); CvScalar colorbox = CV_RGB( 255,160,90); int key=-1; int bandera2=1; /*inicio de captura si no enviaron una ruta de video busca la primera cámara en el sistema y la usa*/ CvCapture* capture = 0; if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 ); else if( argc == 2 ) capture = cvCaptureFromAVI( argv[1] ); if( !capture ) {       fprintf(stderr,"No se pudo iniciar.\n"); return -1; }   printf ("programa de prueba usando CvFGDStatModel y trabajo con contornos %s (%d.%d.%d)\n",    CV_VERSION,    CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION); /*Captura del primer cuadro para inicialización */ IplImage* videoFrame = NULL; videoFrame = cvQueryFrame(capture); if(!videoFrame) {       printf("mal cuadro \n"); exit(0); }   else {       printf("buen cuadro continuo\n"); }   // Crear ventanas

cvNamedWindow("Imagen",1); cvNamedWindow("FG", 1); cvNamedWindow("FG2", 1); cvNamedWindow("BG", 1); cvNamedWindow("bordes",1);

///para crear video descomente

CvVideoWriter* creavideo = cvCreateVideoWriter("videito.avi",-1, 29.95, cvSize(videoFrame->width, videoFrame->height));//el -1 solo funciona con OpenCV 1.0y anteriores para el resto use el macro fourcc if(creavideo == NULL) {       printf("No funciona el video\n"); return(0); }

/*   modelo de fondo y primer plano*/ //   seleccionar los parametros para el modelo gausiano, tambien se puede trabajar con los por defecto si no se entra estos parametros en la funcion constructora del bgModel CvGaussBGStatModelParams* params = new CvGaussBGStatModelParams; params->win_size=3; params->n_gauss=5; params->bg_threshold=0.7; params->std_threshold=3.5; params->minArea=15; params->weight_init=0.05; params->variance_init=50; // crear el GaussianBGModel CvBGStatModel* bgModel = cvCreateGaussianBGModel(videoFrame ,params); //Crea el StatModel

// /*variables para encontrar contornos*/ // CvMemStorage* storage = cvCreateMemStorage(0);//crea el storage para los contornos // CvSeq* result; // CvSeq* contour = 0;//crea la secuencia de contornos

/*variables para bordes*/ int iteraciones = 1; IplConvKernel * mascara = cvCreateStructuringElementEx(3, 3, 1, 1,CV_SHAPE_ELLIPSE,NULL); IplImage * erodada = NULL; IplImage * bordes = NULL; IplImage * threshold = NULL; erodada = cvCreateImage(cvSize(videoFrame->width, videoFrame->height), videoFrame->depth ,videoFrame->nChannels); erodada->origin=videoFrame->origin; bordes = cvCreateImage(cvSize(videoFrame->width,videoFrame->height),videoFrame->depth,videoFrame->nChannels); bordes->origin=videoFrame->origin;

/*variables para modelo de fondo*/ IplImage* copyfore = cvCreateImage(cvSize(videoFrame->width,videoFrame->height),IPL_DEPTH_8U,1);//Crea una imagen con un solo canal para copiar el primer plano hay que hacerlo, no se puede modificar ni tocar el del bgmodel copyfore->origin=1;//Note que no use el mismo de la original coo lo habia hecho antes "EJERCICIO: POR QUE ? " IplImage* imgtemp = cvCreateImage(cvSize(videoFrame->width,videoFrame->height),IPL_DEPTH_8U,1); imgtemp->origin=1; IplImage* imgtemp2 = cvCreateImage(cvSize(videoFrame->width,videoFrame->height),IPL_DEPTH_8U,1); imgtemp2->origin=1; while(key != 'q') {   /*variables para encontrar contornos hay uno mas arriba, es para mostrar como NO se deben usar los contornos, ya que crean una pequeña fuga en memoria, para verla comente las siguientes 3 lineas y la que dice cvReleaseMemStorage( &storage ); al final del for y descomente estas mismas 3 que se encuentran mas arriba y después vea la tarea en el administrador de memoria*/ CvMemStorage* storage = cvCreateMemStorage(0);//crea el storage para los contornos CvSeq* result; CvSeq* contour = 0;//crea la secuencia de contornos

if(bandera2)//para mostrar como salir ejemplo para ver como hacer algo una sola vez en este caso en el primer frame que se procesa {           printf("q para salir \n"); bandera2=0; }       // toma otro cuadro el automaticamente apunto al segundo del video o al mas reciente de la cámara videoFrame = cvQueryFrame(capture); if( !videoFrame ) break; //para bordes cvErode(videoFrame,erodada,mascara,iteraciones); //resta la imagen erodada de la original cvSub(videoFrame, erodada, bordes,0); //Otra técnica de obtención de bordes: ojo solo trabaja en una canal //cvCanny(videoFrame, erodada, 80, 90);//NO FUNCIONA ASI NO MAS ES SOLO UN EJEMPLO HAY QUE SEPARAR CANALES PRIMERO o usar blanco y negro cvThreshold(bordes,bordes,15.0,255.0,CV_THRESH_BINARY);

/*Modelo de fondo y primer plano*/ cvUpdateBGStatModel(videoFrame,bgModel);

//Mostrar resultados bgModel->background->origin=1;//Sirve para girar la respuesta en 1.0 bgModel->foreground->origin=1;

//Para encontrar los contornos que hay en la imagen de primer plano cvCopy(bgModel->foreground,copyfore); //Copia la Información del foreground en una imagen temporal cvDilate(copyfore,imgtemp,mascara,3);// cvErode(imgtemp,imgtemp2,mascara,3);//trata esa imagen para que no se vea feita :)

cvFindContours( copyfore, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL);//Se encuentran los contornos en la copia del foreground //note que solo saco los contornos mas externos usando CV_RETR_EXTERNAL //Ejercicio, averiguar que metodo usa cuando no se introduce metodo como en el ejemplo, ver api de cvFindContours :)       // descomente la siguiente si quiere que se aproximen los contornos el penúltimo parametro es el que da la aproximación ojo con posibles problemas de memoria por reasignar apuntador mejor cree uno nuevo con storage nuevo y lo desocupa cuando no lo use:)  "NO ESTA PROBADO" //contour = cvApproxPoly( contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 5, 1 ); while( contour ) {           if(fabs(cvContourArea(contour,CV_WHOLE_SEQ)) > 600)//filtro de contornos por area {           result = cvApproxPoly( contour, sizeof(CvContour), storage,            CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0 );//cvContourPerimeter(contour)*0.02 es una aproximación del autor, lo uso unicamente para mostrar como se halla el perimetro de un contorno, se puede hacer lo mismo con el area y muchas mas medidas cvDrawContours( videoFrame, result, colorext, colorint, 2, CV_FILLED,8 ); bndRect = cvBoundingRect(contour, 0);//Retorna la aproximación en rectángulos de cada uno de los contornos. descomente arriba la declaración de bndRect cvRectangle( videoFrame, cvPoint(bndRect.x,bndRect.y), cvPoint(bndRect.x+bndRect.width,bndRect.y+bndRect.height), colorbox,2, 8, 0 ); cvClearSeq(result); }           // apunte al siguiente contorno contour = contour->h_next; }               //para crear video descomente la siguiente linea cvWriteFrame(creavideo, videoFrame); /* remplace CV_FILLED con 1 para ver solo el exterior */ /*cvDrawContours( videoFrame, contour,                           colorext, colorint,                            2, CV_FILLED,                            8 );*/ //void cvDrawContours( CvArr *image, CvSeq* contour,       //                     double external_color, double hole_color,        //                     int max_level, int thickness=1,        //                     int connectivity=8 ); cvShowImage("FG", bgModel->foreground);//hay que tener cuidado las operaciones morfologicas degeneran la imagen origen por ejemplo mire copyfore no es como deberia ser cvShowImage("FG2", imgtemp2); cvShowImage("BG", bgModel->background); cvShowImage("bordes", bordes); cvShowImage("Imagen",videoFrame); key = cvWaitKey(10); cvReleaseMemStorage( &storage );//COMENTE ESTA LINEA TAMBIËN PARA VER FUGA DE MEMORIA DE LOS CONTORNOS

}       //cvReleaseImage(&videoFrame);//Notese que esta no se libera, como prueba descomente y aprecie el bonito error que se genera en la capruta :)        cvReleaseImage(&imgtemp);        cvReleaseImage(&erodada);        cvReleaseImage(&bordes);    //para grabar no olvide liberar o si no se crea mal el video, esto también cierra el video OJO IMPORTANTE LEA PARA HACER VIDEO    cvReleaseVideoWriter(&creavideo);    cvReleaseBGStatModel(&bgModel);    cvReleaseCapture(&capture);    return 0; } code