5 /* select the correct function for doing case insensitive string comparaison */
7 #define MY_STRNICMP strnicmp
8 #define MY_STRICMP stricmp
10 #define MY_STRNICMP strncasecmp
11 #define MY_STRICMP strcasecmp
14 /* list of FG DETECTION modules */
15 static CvFGDetector* cvCreateFGDetector0(){return cvCreateFGDetectorBase(CV_BG_MODEL_FGD, NULL);}
16 static CvFGDetector* cvCreateFGDetector0Simple(){return cvCreateFGDetectorBase(CV_BG_MODEL_FGD_SIMPLE, NULL);}
17 static CvFGDetector* cvCreateFGDetector1(){return cvCreateFGDetectorBase(CV_BG_MODEL_MOG, NULL);}
18 typedef struct DefModule_FGDetector
20 CvFGDetector* (*create)();
23 } DefModule_FGDetector;
24 DefModule_FGDetector FGDetector_Modules[] =
26 {cvCreateFGDetector0,"FG_0","Foreground Object Detection from Videos Containing Complex Background. ACM MM2003."},
27 {cvCreateFGDetector0Simple,"FG_0S","Simplyfied version of FG_0"},
28 {cvCreateFGDetector1,"FG_1","Adaptive background mixture models for real-time tracking. CVPR1999"},
32 /* list of BLOB DETECTION modules */
33 typedef struct DefModule_BlobDetector
35 CvBlobDetector* (*create)();
38 } DefModule_BlobDetector;
39 DefModule_BlobDetector BlobDetector_Modules[] =
41 {cvCreateBlobDetectorCC,"BD_CC","Detect new blob by tracking CC of FG mask"},
42 {cvCreateBlobDetectorSimple,"BD_Simple","Detect new blob by uniform moving of connected components of FG mask"},
46 /* list of BLOB TRACKING modules */
47 typedef struct DefModule_BlobTracker
49 CvBlobTracker* (*create)();
52 } DefModule_BlobTracker;
53 DefModule_BlobTracker BlobTracker_Modules[] =
55 {cvCreateBlobTrackerCCMSPF,"CCMSPF","connected component tracking and MSPF resolver for collision"},
56 {cvCreateBlobTrackerCC,"CC","Simple connected component tracking"},
57 {cvCreateBlobTrackerMS,"MS","Mean shift algorithm "},
58 {cvCreateBlobTrackerMSFG,"MSFG","Mean shift algorithm with FG mask using"},
59 {cvCreateBlobTrackerMSPF,"MSPF","Particle filtering based on MS weight"},
63 /* list of BLOB TRAJECTORY GENERATION modules */
64 typedef struct DefModule_BlobTrackGen
66 CvBlobTrackGen* (*create)();
69 } DefModule_BlobTrackGen;
70 DefModule_BlobTrackGen BlobTrackGen_Modules[] =
72 {cvCreateModuleBlobTrackGenYML,"YML","Generate track record in YML format as synthetic video data"},
73 {cvCreateModuleBlobTrackGen1,"RawTracks","Generate raw track record (x,y,sx,sy),()... in each line"},
77 /* list of BLOB TRAJECTORY POST PROCESSING modules */
78 typedef struct DefModule_BlobTrackPostProc
80 CvBlobTrackPostProc* (*create)();
83 } DefModule_BlobTrackPostProc;
84 DefModule_BlobTrackPostProc BlobTrackPostProc_Modules[] =
86 {cvCreateModuleBlobTrackPostProcKalman,"Kalman","Kalman filtering of blob position and size"},
87 {NULL,"None","No post processing filter"},
88 // {cvCreateModuleBlobTrackPostProcTimeAverRect,"TimeAverRect","Average by time using rectangle window"},
89 // {cvCreateModuleBlobTrackPostProcTimeAverExp,"TimeAverExp","Average by time using exponential window"},
93 /* list of BLOB TRAJECTORY ANALYSIS modules */
94 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisDetector();
96 typedef struct DefModule_BlobTrackAnalysis
98 CvBlobTrackAnalysis* (*create)();
101 } DefModule_BlobTrackAnalysis;
102 DefModule_BlobTrackAnalysis BlobTrackAnalysis_Modules[] =
104 {cvCreateModuleBlobTrackAnalysisHistPVS,"HistPVS","Histogramm of 5D feture vector analysis (x,y,vx,vy,state)"},
105 {NULL,"None","No trajectory analiser"},
106 {cvCreateModuleBlobTrackAnalysisHistP,"HistP","Histogramm of 2D feture vector analysis (x,y)"},
107 {cvCreateModuleBlobTrackAnalysisHistPV,"HistPV","Histogramm of 4D feture vector analysis (x,y,vx,vy)"},
108 {cvCreateModuleBlobTrackAnalysisHistSS,"HistSS","Histogramm of 4D feture vector analysis (startpos,endpos)"},
109 {cvCreateModuleBlobTrackAnalysisTrackDist,"TrackDist","Compare tracks directly"},
110 {cvCreateModuleBlobTrackAnalysisIOR,"IOR","Integrator (by OR operation) of several analysers "},
113 /* list of Blob Trajectory ANALYSIS modules */
114 /*================= END MODULES DECRIPTION ===================================*/
116 /* run pipeline on all frames */
117 static int RunBlobTrackingAuto( CvCapture* pCap, CvBlobTrackerAuto* pTracker,char* fgavi_name = NULL, char* btavi_name = NULL )
119 int OneFrameProcess = 0;
122 CvVideoWriter* pFGAvi = NULL;
123 CvVideoWriter* pBTAvi = NULL;
125 //cvNamedWindow( "FG", 0 );
128 for( FrameNum=0; pCap && (key=cvWaitKey(OneFrameProcess?0:1))!=27;
131 IplImage* pImg = NULL;
132 IplImage* pMask = NULL;
137 if(key=='r')OneFrameProcess = 0;
140 pImg = cvQueryFrame(pCap);
141 if(pImg == NULL) break;
145 pTracker->Process(pImg, pMask);
148 if(pTracker->GetFGMask())
150 IplImage* pFG = pTracker->GetFGMask();
151 CvSize S = cvSize(pFG->width,pFG->height);
152 static IplImage* pI = NULL;
154 if(pI==NULL)pI = cvCreateImage(S,pFG->depth,3);
155 cvCvtColor( pFG, pI, CV_GRAY2BGR );
158 {/* save fg to avi file */
161 pFGAvi=cvCreateVideoWriter(
163 CV_FOURCC('x','v','i','d'),
167 cvWriteFrame( pFGAvi, pI );
170 if(pTracker->GetBlobNum()>0)
171 {/* draw detected blobs */
173 for(i=pTracker->GetBlobNum();i>0;i--)
175 CvBlob* pB = pTracker->GetBlob(i-1);
176 CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
177 CvSize s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB))), MAX(1,cvRound(CV_BLOB_RY(pB))));
178 int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
183 CV_RGB(c,255-c,0), cvRound(1+(3*c)/255) );
187 cvNamedWindow( "FG",0);
188 cvShowImage( "FG",pI);
192 /* draw debug info */
194 {/* draw all inforamtion about tets sequence */
196 int line_type = CV_AA; // change it to 8 to see non-antialiased graphics
199 IplImage* pI = cvCloneImage(pImg);
201 cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 0.7, 0.7, 0, 1, line_type );
203 for(i=pTracker->GetBlobNum();i>0;i--)
206 CvBlob* pB = pTracker->GetBlob(i-1);
207 CvPoint p = cvPoint(cvRound(pB->x*256),cvRound(pB->y*256));
208 CvSize s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB)*256)), MAX(1,cvRound(CV_BLOB_RY(pB)*256)));
209 int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
215 CV_RGB(c,255-c,0), cvRound(1+(3*0)/255), CV_AA, 8 );
220 sprintf(str,"%03d",CV_BLOB_ID(pB));
221 cvGetTextSize( str, &font, &TextSize, NULL );
223 cvPutText( pI, str, p, &font, CV_RGB(0,255,255));
225 char* pS = pTracker->GetStateDesc(CV_BLOB_ID(pB));
228 char* pStr = strdup(pS);
229 char* pStrFree = pStr;
230 for(;pStr && strlen(pStr)>0;)
232 char* str_next = strchr(pStr,'\n');
238 p.y += TextSize.height+1;
239 cvPutText( pI, pStr, p, &font, CV_RGB(0,255,255));
248 cvNamedWindow( "Tracking", 0);
249 cvShowImage( "Tracking",pI );
252 {/* save to avi file */
253 CvSize S = cvSize(pI->width,pI->height);
256 pBTAvi=cvCreateVideoWriter(
258 CV_FOURCC('x','v','i','d'),
262 cvWriteFrame( pBTAvi, pI );
266 }/* draw all inforamtion about tets sequence */
269 if(pFGAvi)cvReleaseVideoWriter( &pFGAvi );
270 if(pBTAvi)cvReleaseVideoWriter( &pBTAvi );
272 }/* RunBlobTrackingAuto */
274 /* read parameters from command line and transfer to specified module */
275 static void set_params(int argc, char* argv[], CvVSModule* pM, char* prefix, char* module)
277 int prefix_len = strlen(prefix);
285 if(MY_STRNICMP(prefix,cmd,prefix_len)!=0) continue;
287 if(cmd[0]!=':')continue;
290 ptr_eq = strchr(cmd,'=');
291 if(ptr_eq)cmd_param_len = ptr_eq-cmd;
295 char* param = pM->GetParamName(j);
296 if(param==NULL) break;
297 param_len = strlen(param);
298 if(cmd_param_len!=param_len) continue;
299 if(MY_STRNICMP(param,cmd,param_len)!=0) continue;
301 if(cmd[0]!='=')continue;
303 pM->SetParamStr(param,cmd);
304 printf("%s:%s param set to %g\n",module,param,pM->GetParam(param));
310 /* print all parameters value for given module */
311 static void print_params(CvVSModule* pM, char* module, char* log_name)
313 FILE* log = log_name?fopen(log_name,"at"):NULL;
315 if(pM->GetParamName(0) == NULL ) return;
318 printf("%s(%s) module parameters:\n",module,pM->GetNickName());
320 fprintf(log,"%s(%s) module parameters:\n",module,pM->GetNickName());
323 char* param = pM->GetParamName(i);
324 char* str = param?pM->GetParamStr(param):NULL;
325 if(param == NULL)break;
328 printf(" %s: %s\n",param,str);
330 fprintf(log," %s: %s\n",param,str);
334 printf(" %s: %g\n",param,pM->GetParam(param));
336 fprintf(log," %s: %g\n",param,pM->GetParam(param));
342 int main(int argc, char* argv[])
344 CvCapture* pCap = NULL;
345 CvBlobTrackerAutoParam1 param = {0};
346 CvBlobTrackerAuto* pTracker = NULL;
349 char* scale_name = NULL;
350 char* yml_name = NULL;
351 char** yml_video_names = NULL;
352 int yml_video_num = 0;
353 char* avi_name = NULL;
354 char* fg_name = NULL;
355 char* fgavi_name = NULL;
356 char* btavi_name = NULL;
357 char* bd_name = NULL;
358 char* bt_name = NULL;
359 char* btgen_name = NULL;
360 char* btpp_name = NULL;
361 char* bta_name = NULL;
362 char* bta_data_name = NULL;
363 char* track_name = NULL;
364 char* comment_name = NULL;
365 char* FGTrainFrames = NULL;
366 char* log_name = NULL;
367 char* savestate_name = NULL;
368 char* loadstate_name = NULL;
369 char* bt_corr = NULL;
370 DefModule_FGDetector* pFGModule = NULL;
371 DefModule_BlobDetector* pBDModule = NULL;
372 DefModule_BlobTracker* pBTModule = NULL;
373 DefModule_BlobTrackPostProc* pBTPostProcModule = NULL;
374 DefModule_BlobTrackGen* pBTGenModule = NULL;
375 DefModule_BlobTrackAnalysis* pBTAnalysisModule = NULL;
377 cvInitSystem(argc, argv);
382 printf("blobtrack [fg=<fg_name>] [bd=<bd_name>]\n"
383 " [bt=<bt_name>] [btpp=<btpp_name>]\n"
385 " [bta_data=<bta_data_name>\n"
386 " [bt_corr=<bt_corr_way>]\n"
387 " [btgen=<btgen_name>]\n"
388 " [track=<track_file_name>]\n"
389 " [scale=<scale val>] [noise=<noise_name>] [IVar=<IVar_name>]\n"
390 " [FGTrainFrames=<FGTrainFrames>]\n"
391 " [btavi=<avi output>] [fgavi=<avi output on FG>]\n"
393 printf(" <bt_corr_way> is way of blob position corrrection for \"Blob Tracking\" module\n"
394 " <bt_corr_way>=none,PostProcRes\n"
395 " <FGTrainFrames> is number of frames for FG training\n"
396 " <track_file_name> is file name for save tracked trajectories\n"
397 " <bta_data> is file name for data base of trajectory analysis module\n"
398 " <avi_file> is file name of avi to process by BlobTrackerAuto\n");
401 #define PR(_name,_m,_mt)\
402 printf("<%s> is \"%s\" module name and can be:\n",_name,_mt);\
403 for(i=0;_m[i].nickname;++i)\
405 printf(" %d. %s",i+1,_m[i].nickname);\
406 if(_m[i].description)printf(" - %s",_m[i].description);\
410 PR("fg_name",FGDetector_Modules,"FG/BG Detection");
411 PR("bd_name",BlobDetector_Modules,"Blob Entrance Detection");
412 PR("bt_name",BlobTracker_Modules,"Blob Tracking");
413 PR("btpp_name",BlobTrackPostProc_Modules, "Blob Trajectory Post Processing");
414 PR("btgen_name",BlobTrackGen_Modules, "Blob Trajectory Generation");
415 PR("bta_name",BlobTrackAnalysis_Modules, "Blob Trajectory Analysis");
420 {/* parse srguments */
425 size_t len = strlen(argv[i]);
426 #define RO(_n1,_n2) if(strncmp(argv[i],_n1,strlen(_n1))==0) {_n2 = argv[i]+strlen(_n1);bParsed=1;};
428 RO("fgavi=",fgavi_name);
429 RO("btavi=",btavi_name);
432 RO("bt_corr=",bt_corr);
433 RO("btpp=",btpp_name);
435 RO("bta_data=",bta_data_name);
436 RO("btgen=",btgen_name);
437 RO("track=",track_name);
438 RO("comment=",comment_name);
439 RO("FGTrainFrames=",FGTrainFrames);
441 RO("savestate=",savestate_name);
442 RO("loadstate=",loadstate_name);
445 char* ext = argv[i] + len-4;
446 if( strrchr(argv[i],'=') == NULL &&
448 (len>3 && (MY_STRICMP(ext,".avi") == 0 )))
455 }/* parse srguments */
458 {/* set Trajectory Generator module */
460 if(!btgen_name)btgen_name=BlobTrackGen_Modules[0].nickname;
461 for(i=0;BlobTrackGen_Modules[i].nickname;++i)
463 if(MY_STRICMP(BlobTrackGen_Modules[i].nickname,btgen_name)==0)
464 pBTGenModule = BlobTrackGen_Modules + i;
466 }/* set Trajectory Generato modulke */
468 /* init postprocessing module if tracker correction by postporcessing is reqierd */
469 if(bt_corr && MY_STRICMP(bt_corr,"PostProcRes")!=0 && !btpp_name)
472 if(MY_STRICMP(btpp_name,"none")!=0)bt_corr = "PostProcRes";
475 {/* set default parameters for one processing */
476 if(!bt_corr) bt_corr = "none";
477 if(!fg_name) fg_name = FGDetector_Modules[0].nickname;
478 if(!bd_name) bd_name = BlobDetector_Modules[0].nickname;
479 if(!bt_name) bt_name = BlobTracker_Modules[0].nickname;
480 if(!btpp_name) btpp_name = BlobTrackPostProc_Modules[0].nickname;
481 if(!bta_name) bta_name = BlobTrackAnalysis_Modules[0].nickname;
482 if(!scale_name) scale_name = "1";
486 scale = (float)atof(scale_name);
487 for(pFGModule=FGDetector_Modules;pFGModule->nickname;++pFGModule)
488 if( fg_name && MY_STRICMP(fg_name,pFGModule->nickname)==0 ) break;
489 for(pBDModule=BlobDetector_Modules;pBDModule->nickname;++pBDModule)
490 if( bd_name && MY_STRICMP(bd_name,pBDModule->nickname)==0 ) break;
491 for(pBTModule=BlobTracker_Modules;pBTModule->nickname;++pBTModule)
492 if( bt_name && MY_STRICMP(bt_name,pBTModule->nickname)==0 ) break;
493 for(pBTPostProcModule=BlobTrackPostProc_Modules;pBTPostProcModule->nickname;++pBTPostProcModule)
494 if( btpp_name && MY_STRICMP(btpp_name,pBTPostProcModule->nickname)==0 ) break;
495 for(pBTAnalysisModule=BlobTrackAnalysis_Modules;pBTAnalysisModule->nickname;++pBTAnalysisModule)
496 if( bta_name && MY_STRICMP(bta_name,pBTAnalysisModule->nickname)==0 ) break;
498 /* create source video */
500 pCap = cvCaptureFromFile(avi_name);
504 printf("Can't open %s file\n",avi_name);
509 {/* display parameters */
511 FILE* log = log_name?fopen(log_name,"at"):NULL;
513 {/* print to log file */
514 fprintf(log,"\n=== Blob Tracking pipline in processing mode===\n");
517 fprintf(log,"AVIFile: %s\n",avi_name);
519 fprintf(log,"FGDetector: %s\n", pFGModule->nickname);
520 fprintf(log,"BlobDetector: %s\n", pBDModule->nickname);
521 fprintf(log,"BlobTracker: %s\n", pBTModule->nickname);
522 fprintf(log,"BlobTrackPostProc: %s\n", pBTPostProcModule->nickname);
523 fprintf(log,"BlobCorrection: %s\n", bt_corr);
524 fprintf(log,"Blob Trajectory Generator: %s (%s)\n",
525 pBTGenModule?pBTGenModule->nickname:"None",
526 track_name?track_name:"none");
527 fprintf(log,"BlobTrackAnalysis: %s\n", pBTAnalysisModule->nickname);
531 printf("\n=== Blob Tracking pipline in %s mode===\n","processing");
534 printf("ConfigFile: %s\n",yml_name);
535 printf("BG: %s\n",yml_video_names[0]);
537 for(i=1;i<(yml_video_num);++i){printf(yml_video_names[i]);if((i+1)<yml_video_num)printf("|");};
542 printf("AVIFile: %s\n",avi_name);
544 printf("FGDetector: %s\n", pFGModule->nickname);
545 printf("BlobDetector: %s\n", pBDModule->nickname);
546 printf("BlobTracker: %s\n", pBTModule->nickname);
547 printf("BlobTrackPostProc: %s\n", pBTPostProcModule->nickname);
548 printf("BlobCorrection: %s\n", bt_corr);
549 printf("Blob Trajectory Generator: %s (%s)\n",
550 pBTGenModule?pBTGenModule->nickname:"None",
551 track_name?track_name:"none");
552 printf("BlobTrackAnalysis: %s\n", pBTAnalysisModule->nickname);
554 }/* display parameters */
556 { /* create autotracker module and its components*/
557 param.FGTrainFrames = FGTrainFrames?atoi(FGTrainFrames):0;
559 /* Create FG Detection module */
560 param.pFG = pFGModule->create();
562 puts("Can not create FGDetector module");
563 param.pFG->SetNickName(pFGModule->nickname);
564 set_params(argc, argv, param.pFG, "fg", pFGModule->nickname);
566 /* Create Blob Entrance Detection module */
567 param.pBD = pBDModule->create();
569 puts("Can not create BlobDetector module");
570 param.pBD->SetNickName(pBDModule->nickname);
571 set_params(argc, argv, param.pBD, "bd", pBDModule->nickname);
573 /* Create blob tracker module */
574 param.pBT = pBTModule->create();
576 puts("Can not create BlobTracker module");
577 param.pBT->SetNickName(pBTModule->nickname);
578 set_params(argc, argv, param.pBT, "bt", pBTModule->nickname);
580 /* create blob trajectory generation module */
582 if(pBTGenModule && track_name && pBTGenModule->create)
584 param.pBTGen = pBTGenModule->create();
585 param.pBTGen->SetFileName(track_name);
589 param.pBTGen->SetNickName(pBTGenModule->nickname);
590 set_params(argc, argv, param.pBTGen, "btgen", pBTGenModule->nickname);
593 /* create blob trajectory post processing module */
595 if(pBTPostProcModule && pBTPostProcModule->create)
597 param.pBTPP = pBTPostProcModule->create();
601 param.pBTPP->SetNickName(pBTPostProcModule->nickname);
602 set_params(argc, argv, param.pBTPP, "btpp", pBTPostProcModule->nickname);
605 param.UsePPData = (bt_corr && MY_STRICMP(bt_corr,"PostProcRes")==0);
607 /* create blob trajectory analysis module */
609 if(pBTAnalysisModule && pBTAnalysisModule->create)
611 param.pBTA = pBTAnalysisModule->create();
612 param.pBTA->SetFileName(bta_data_name);
616 param.pBTA->SetNickName(pBTAnalysisModule->nickname);
617 set_params(argc, argv, param.pBTA, "bta", pBTAnalysisModule->nickname);
620 /* create whole pipline */
621 pTracker = cvCreateBlobTrackerAuto1(¶m);
623 puts("Can not create BlobTrackerAuto");
626 { /* load states of each module from state file */
627 CvFileStorage* fs = NULL;
629 fs=cvOpenFileStorage(loadstate_name,NULL,CV_STORAGE_READ);
632 printf("Load states for modules...\n");
635 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTracker");
636 param.pBT->LoadState(fs,fn);
641 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackAnalyser");
642 param.pBTA->LoadState(fs,fn);
647 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackerAuto");
648 pTracker->LoadState(fs,fn);
651 cvReleaseFileStorage(&fs);
652 printf("... Modules states loaded\n");
654 }/* load states of each module */
656 {/* print modules parameters */
662 {(CvVSModule*)param.pFG,"FGdetector"},
663 {(CvVSModule*)param.pBD,"BlobDetector"},
664 {(CvVSModule*)param.pBT,"BlobTracker"},
665 {(CvVSModule*)param.pBTGen,"TrackGen"},
666 {(CvVSModule*)param.pBTPP,"PostProcessing"},
667 {(CvVSModule*)param.pBTA,"TrackAnalysis"},
671 for(i=0;Modules[i].name;++i)
674 print_params(Modules[i].pM,Modules[i].name,log_name);
676 }/* print modules parameters */
679 RunBlobTrackingAuto( pCap, pTracker, fgavi_name, btavi_name );
681 {/* save state and release modules */
682 CvFileStorage* fs = NULL;
685 fs=cvOpenFileStorage(savestate_name,NULL,CV_STORAGE_WRITE);
689 cvStartWriteStruct(fs,"BlobTracker",CV_NODE_MAP);
690 if(param.pBT)param.pBT->SaveState(fs);
691 cvEndWriteStruct(fs);
692 cvStartWriteStruct(fs,"BlobTrackerAuto",CV_NODE_MAP);
693 if(pTracker)pTracker->SaveState(fs);
694 cvEndWriteStruct(fs);
695 cvStartWriteStruct(fs,"BlobTrackAnalyser",CV_NODE_MAP);
696 if(param.pBTA)param.pBTA->SaveState(fs);
697 cvEndWriteStruct(fs);
698 cvReleaseFileStorage(&fs);
700 if(param.pBT)cvReleaseBlobTracker(¶m.pBT);
701 if(param.pBD)cvReleaseBlobDetector(¶m.pBD);
702 if(param.pBTGen)cvReleaseBlobTrackGen(¶m.pBTGen);
703 if(param.pBTA)cvReleaseBlobTrackAnalysis(¶m.pBTA);
704 if(param.pFG)cvReleaseFGDetector(¶m.pFG);
705 if(pTracker)cvReleaseBlobTrackerAuto(&pTracker);
706 }/* save state and release modules*/
709 cvReleaseCapture(&pCap);