/*!\brief Calcula las medias y varianzas moviles para la cantidad de movimiento * * @param frameDataStats * @param frameDataOut */ void statsBlobS( STFrame* frameDataOut ){ STFly* flyOut = NULL; valorSum* valor = NULL; if(frameDataOut->Flies->numeroDeElementos == 0 ) return; // si no hay datos del frame, no computar // Obtener el nuevo valor valor = ( valorSum *) malloc( sizeof(valorSum)); valor->sum = sumFrame( frameDataOut ->Flies ); anyadirAlFinal( valor, vectorSumFr ); // Si es el primer elemento, iniciar medias if(vectorSumFr->numeroDeElementos == 1){ iniciarMedias( frameDataOut->Stats, valor->sum ); return; } // movimiento global. Calculo de medias y desviaciones mediaMovil( Coef, vectorSumFr, frameDataOut->Stats ); if( (unsigned)vectorSumFr->numeroDeElementos == Coef->FMax){ valor = (valorSum*)liberarPrimero( vectorSumFr ); free(valor); } }
void Validacion2(IplImage *Imagen, STFrame* FrameData, SHModel* SH,StaticBGModel* BGModel, IplImage* Mask) { //Inicializar estructura para almacenar los datos cada mosca STFly *FlyData = NULL; int Exceso;//Flag que indica si la Pxi minima no se alcanza por exceso o por defecto. double Circul; // Para almacenar la circularidad del blob actual double Besthres = 0;// el mejor de los umbrales perteneciente a la mejor probabilidad double BestPxi = 0; // la mejor probabilidad obtenida para cada mosca // Establecemos los parámetros de validación por defecto // establecer los umbrales de resta iniciales if (valParams->privateParams == NULL) { PrivateValParams(SH,BGModel, &valParams->privateParams); } // Establecemos parámetros para los umbrales en la resta de fondo por defecto ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; if( SH->FlyAreaDes == 0){ printf("hola"); } // almacenar una copia del FG para restaurar el blob en caso de que falle la validación cvCopy(FrameData->FG, Mask); // Recorremos los blobs uno por uno y los validamos. // Bucle for desde el primero hasta el ultimo individuo de la Lista FrameData->Flie del frame actual. // Los blobs resultantes de la fisión se añaden al final para ser validados de nuevo if (SHOW_VALIDATION_DATA) mostrarFliesFrame(FrameData); for (int i = 0; i < FrameData->Flies->numeroDeElementos; i++) { // Almacenar la Roi del blob visitado antes de ser validado FlyData = (STFly *) obtener(i, FrameData->Flies); if (FlyData->flag_seg == true) continue; // si el blob ha sido validado y es correcto pasar al siguiente CvRect FlyDataRoi = FlyData->Roi; // Inicializar LOW_THRESHOLD y demas valores ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; FlyData->bestTresh = ValBGParams->LOW_THRESHOLD; // calcular su circularidad Circul = CalcCircul(FlyData); // Comprobar si existe Exceso o Defecto de area, en caso de Exceso la probabilidad del blob es muy pequeña // y el blob puede corresponder a varios blobs que forman parte de una misma moscas o puede corresponder a // un espurio. Exceso = CalcProbFly(SH, FlyData, valParams); // Calcular la px de la mosca. BestPxi = FlyData->Px; STFly* MejorFly = FlyData;// = NULL; // comprobar si está dentro de los límites: // Params->MaxLowTH = *ObtenerMaximo(Imagen, FrameData ,FlyData->Roi); // En caso de EXCESO de Area /* Incrementar paulatinamente el umbral de resta de fondo hasta * que haya fisión o bien desaparzca el blob sin fisionarse o bien * no se supere la pximin. * - Si hay fisión: * -si los blobs tienen una probabilidad mayor que la pximin fin segmentacion * -si alguno de ellos tiene una probabilidad menor a la pximin, restaurar original y aplicar EM * - Si no hay fisión: Si el blob desaparece antes de alcanzar la pximin o * bien alcanza la pximin, restablecer el tamaño original del blob para aplicar EM * */ if (Exceso > 0) { //Inicializar estructura para almacenar la lista de los blobs divididos. tlcde* TempSeg = NULL; ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; // sustituir por un for con el número máximo de iteraciones. int j = 0; while (1) { // primero probar con el umbral anterior. si el blob desaparece o no da un resutado satisfactorio // proceder desde el umbral predetermindado // Incrementar umbral ValBGParams->LOW_THRESHOLD += 1; j++; // Restar fondo BackgroundDifference(Imagen, FrameData->BGModel, NULL, FrameData->FG, ValBGParams, FlyDataRoi); //verMatrizIm(FrameData->FG, FlyDataRoi); // Segmentar TempSeg = segmentacion2(Imagen, FrameData->BGModel, FrameData->FG, FlyDataRoi, NULL); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); // Comprobar si se ha conseguido dividir el blob y verificar si el resultado es optimo // 1) El blob desaparece antes de alcanzar la pximin sin dividirse. Restauramos el blob y pasamos al siguiente elemento. if (TempSeg->numeroDeElementos < 1 || TempSeg == NULL) { RestaurarElMejor(FrameData->Flies, FrameData->FG, MejorFly, FlyDataRoi, i); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); // liberar lista liberarListaFlies(TempSeg); break; } // 2) mientras no haya fisión else if (TempSeg->numeroDeElementos == 1) { FlyData = (STFly *) obtener(0, TempSeg); Exceso = CalcProbFly(SH, FlyData, valParams); // no se rebasa la pximin.Almacenar la probabilidad mas alta y continuar if (Exceso > -1 && j < valParams->MaxIncLTHIters && ValBGParams->LOW_THRESHOLD < valParams->MaxLowTH) { if (FlyData->Px >= BestPxi) { MejorFly = FlyData; BestPxi = FlyData->Px; Besthres = ValBGParams->LOW_THRESHOLD; } liberarListaFlies(TempSeg); free(TempSeg); TempSeg = NULL; continue; } // se ha rebasado la pxmin o bien se ha alcanzado el máximo de iteraciones o bien se ha llegado // al máximo valor permitido. Restaurar y pasar al siguiente else { RestaurarElMejor(FrameData->Flies, FrameData->FG, MejorFly, FlyDataRoi, i); //Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); liberarListaFlies(TempSeg); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); break; } } // 3) Hay fisión else if (TempSeg->numeroDeElementos > 1) { // comprobar si las pxi son válidas. En caso de que todas lo sean eliminar de la lista el blob segmentado // y añadirlas a la lista al final. int exito = comprobarPxi(TempSeg, SH, valParams); if (exito) { borrarEl(i, FrameData->Flies); // se borra el elemento dividido for (int j = 0; j < TempSeg->numeroDeElementos; j++) { // se añaden los nuevos al final FlyData = (STFly *) obtener(j, TempSeg); anyadirAlFinal(FlyData, FrameData->Flies); } if (SHOW_VALIDATION_DATA){ printf("\n Lista Flies tras FISION\n"); mostrarFliesFrame(FrameData); } i--; // decrementar i para no saltarnos un elemento de la lista break; // salir del while } // Se ha rebasado la pximin en alguno de los blobs resultantes. Restauramos y pasamos al sig. blob else { liberarListaFlies(TempSeg); Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); break; // salir del while } } }// Fin del While //liberarListaFlies( TempSeg ); if (TempSeg) free(TempSeg); TempSeg = NULL; } //Fin Exceso /* En el caso de DEFECTO disminuir el umbral, para maximizar la probabilidad del blob * Si no es posible se elimina (spurio) */ else if (Exceso < 0) { STFly* MejorFly = NULL; CvRect newRoi; tlcde* TempSeg = NULL; ValBGParams->LOW_THRESHOLD = valParams->privateParams->LThInicio; ValBGParams->HIGHT_THRESHOLD = valParams->privateParams->HThInicio; newRoi = FlyDataRoi; BestPxi = 0; int j = 0; while (j < valParams->MaxDecLTHIters) { newRoi.height += 1; newRoi.width += 1; newRoi.x -= 1; newRoi.y -= 1; ValBGParams->LOW_THRESHOLD -= 1; if (ValBGParams->LOW_THRESHOLD == valParams->MinLowTH) { Restaurar(FrameData->Flies, FrameData->FG, Mask, FlyDataRoi, i); break; } //while(Exceso < 0 && ValBGParams->LOW_THRESHOLD > Params->MinLowTH && Params->MaxDecLTHIters){ // Restar fondo BackgroundDifference(Imagen, FrameData->BGModel, FrameData->IDesvf, FrameData->FG, ValBGParams, newRoi); // Segmentar TempSeg = segmentacion2(Imagen, FrameData->BGModel, FrameData->FG, newRoi, NULL); //TempSeg = segmentacion(Imagen, FrameData, newRoi,NULL); DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); if (TempSeg == NULL || TempSeg->numeroDeElementos < 1) continue; // Calcular la pxi FlyData = (STFly *) obtener(0, TempSeg); Exceso = CalcProbFly(SH, FlyData, valParams); // Calcular la px de la mosca. // mientras la probabilidad se incremente continuamos decrementando el umbral j++; if (FlyData->Px >= BestPxi) { MejorFly = (STFly *) obtener(0, TempSeg); BestPxi = FlyData->Px; Besthres = ValBGParams->LOW_THRESHOLD; } else if (FlyData->Px < BestPxi || j == valParams->MaxDecLTHIters) { // cuando deje de mejorar o bien se llegue al máximo de iteraciones //nos quedamos con aquel que dio la mejor probabilidad. Lo insertamos en la lista en la misma posición. DraWWindow(FrameData->FG, NULL, NULL, SHOW_VALIDATION_IMAGES, COMPLETO ); sustituirEl(MejorFly, FrameData->Flies, i); break; } liberarListaFlies(TempSeg); if (TempSeg) { free(TempSeg); TempSeg = NULL; } }// FIN WHILE liberarListaFlies(TempSeg); if (TempSeg) free(TempSeg); }// FIN DEFECTO }//FOR dibujarBGFG( FrameData->Flies,FrameData->FG,1); if (valParams->CleanGhosts){ cleanGhosts(FrameData->FG, FrameData->Flies); dibujarBGFG( FrameData->Flies,FrameData->FG,1); cvAdd( FrameData->FG, maskCleanGhost, FrameData->FG); } }//Fin de Validación
STFrame* Tracking( STFrame* frameDataIn, int MaxTracks,StaticBGModel* BGModel, int FPS ){ STFrame* frameDataOut = NULL; // frame de salida #ifdef MEDIR_TIEMPOS struct timeval ti,tif; // iniciamos la estructura float tiempoParcial; gettimeofday(&tif, NULL); printf("\n2)Tracking:\n"); gettimeofday(&ti, NULL); printf("\t1)Asignación de identidades\n"); #endif ////////////// AÑADIR AL BUFFER ///////////// anyadirAlFinal( frameDataIn, framesBuf); // MotionTemplate( framesBuf,Identities ); ////////////// ASIGNACIÓN DE IDENTIDADES /////////// //APLICAR EL METODO DE OPTIMIZACION HUNGARO A LA MATRIZ DE PESOS // Asignar identidades. // resolver las asociaciones usando las predicciones de kalman mediante el algoritmo Hungaro // Si varias dan a la misma etiquetarla como 0. Enlazar flies. // Se trabaja en las posiciones frame MAX_BUFFER - 1 y MAX_BUFFER -2. asignarIdentidades( lsTracks,frameDataIn->Flies); ordenarTracks( lsTracks ); #ifdef MEDIR_TIEMPOS tiempoParcial= obtenerTiempo( ti, 0); printf("\t\t-Tiempo: %5.4g ms\n", tiempoParcial); gettimeofday(&ti, NULL); fprintf(stderr,"\t2)Filtro de Kalman\n"); #endif /////////////// ELIMIRAR FALSOS TRACKS. APLICACIÓN DE HEURíSTICAS AL FINAL DEL BUFFER /// frameDataIn->numTracks = validarTracks( framesBuf, lsTracks,Identities, trackParams->MaxBlobs, frameDataIn->num_frame ); /////////////// FILTRO DE KALMAN ////////////// // El filtro de kalman trabaja en la posicion MAX_BUFFER -1. Ultimo elemento anyadido. Kalman( frameDataIn , Identities, lsTracks, trackParams); frameDataIn->Tracks = lsTracks; #ifdef MEDIR_TIEMPOS tiempoParcial= obtenerTiempo( ti, 0); printf("\t\t-Tiempo: %5.4g ms\n", tiempoParcial); #endif /////// FASE DE CORRECCIÓN. APLICACION DE HEURISTICAS AL FRAME DE SALIDA ///////// despertarTrack(framesBuf, lsTracks, Identities ); ordenarTracks( lsTracks ); // SI BUFFER LLENO if( framesBuf->numeroDeElementos == trackParams->MaxBuffer ){ corregirTracks(framesBuf, lsTracks, Identities ); ////////// LIBERAR MEMORIA //////////// frameDataOut = (STFrame*)liberarPrimero( framesBuf ) ; if(!frameDataOut){error(7); exit(1);} VisualizarEl( framesBuf, PENULTIMO, BGModel ); #ifdef MEDIR_TIEMPOS tiempoParcial = obtenerTiempo( tif , NULL); printf("Tracking correcto.Tiempo total %5.4g ms\n", tiempoParcial); #endif return frameDataOut; } else { VerEstadoBuffer( frameDataIn->Frame, framesBuf->numeroDeElementos, trackParams->MaxBuffer); VisualizarEl( framesBuf, PENULTIMO, BGModel ); #ifdef MEDIR_TIEMPOS tiempoParcial = obtenerTiempo( tif , NULL); printf("Tracking correcto.Tiempo total %5.4g ms\n", tiempoParcial); #endif return 0; } }