90f670d06e2275e5364c87897ee666558b3c895d
[platform/upstream/opencv.git] / samples / c / blobtrack_sample.cpp
1 #include "opencv2/video/background_segm.hpp"
2 #include "opencv2/legacy/blobtrack.hpp"
3 #include "opencv2/legacy/legacy.hpp"
4 #include <opencv2/highgui/highgui_c.h>
5 #include <opencv2/imgproc/imgproc_c.h>
6
7 #include <stdio.h>
8
9 /* Select appropriate case insensitive string comparison function: */
10 #if defined WIN32 || defined _MSC_VER
11 # define MY_STRNICMP _strnicmp
12 # define MY_STRICMP _stricmp
13 # define MY_STRDUP _strdup
14 #else
15 # define MY_STRNICMP strncasecmp
16 # define MY_STRICMP strcasecmp
17 # define MY_STRDUP strdup
18 #endif
19
20 /* List of foreground (FG) DETECTION modules: */
21 static CvFGDetector* cvCreateFGDetector0      () { return cvCreateFGDetectorBase(CV_BG_MODEL_FGD,        NULL); }
22 static CvFGDetector* cvCreateFGDetector0Simple() { return cvCreateFGDetectorBase(CV_BG_MODEL_FGD_SIMPLE, NULL); }
23 static CvFGDetector* cvCreateFGDetector1      () { return cvCreateFGDetectorBase(CV_BG_MODEL_MOG,        NULL); }
24
25 typedef struct DefModule_FGDetector
26 {
27     CvFGDetector* (*create)();
28     const char* nickname;
29     const char* description;
30 } DefModule_FGDetector;
31
32 DefModule_FGDetector FGDetector_Modules[] =
33 {
34     {cvCreateFGDetector0,"FG_0","Foreground Object Detection from Videos Containing Complex Background. ACM MM2003."},
35     {cvCreateFGDetector0Simple,"FG_0S","Simplified version of FG_0"},
36     {cvCreateFGDetector1,"FG_1","Adaptive background mixture models for real-time tracking. CVPR1999"},
37     {NULL,NULL,NULL}
38 };
39
40 /* List of BLOB DETECTION modules: */
41 typedef struct DefModule_BlobDetector
42 {
43     CvBlobDetector* (*create)();
44     const char* nickname;
45     const char* description;
46 } DefModule_BlobDetector;
47
48 DefModule_BlobDetector BlobDetector_Modules[] =
49 {
50     {cvCreateBlobDetectorCC,"BD_CC","Detect new blob by tracking CC of FG mask"},
51     {cvCreateBlobDetectorSimple,"BD_Simple","Detect new blob by uniform moving of connected components of FG mask"},
52     {NULL,NULL,NULL}
53 };
54
55 /* List of BLOB TRACKING modules: */
56 typedef struct DefModule_BlobTracker
57 {
58     CvBlobTracker* (*create)();
59     const char* nickname;
60     const char* description;
61 } DefModule_BlobTracker;
62
63 DefModule_BlobTracker BlobTracker_Modules[] =
64 {
65     {cvCreateBlobTrackerCCMSPF,"CCMSPF","connected component tracking and MSPF resolver for collision"},
66     {cvCreateBlobTrackerCC,"CC","Simple connected component tracking"},
67     {cvCreateBlobTrackerMS,"MS","Mean shift algorithm "},
68     {cvCreateBlobTrackerMSFG,"MSFG","Mean shift algorithm with FG mask using"},
69     {cvCreateBlobTrackerMSPF,"MSPF","Particle filtering based on MS weight"},
70     {NULL,NULL,NULL}
71 };
72
73 /* List of BLOB TRAJECTORY GENERATION modules: */
74 typedef struct DefModule_BlobTrackGen
75 {
76     CvBlobTrackGen* (*create)();
77     const char* nickname;
78     const char* description;
79 } DefModule_BlobTrackGen;
80
81 DefModule_BlobTrackGen BlobTrackGen_Modules[] =
82 {
83     {cvCreateModuleBlobTrackGenYML,"YML","Generate track record in YML format as synthetic video data"},
84     {cvCreateModuleBlobTrackGen1,"RawTracks","Generate raw track record (x,y,sx,sy),()... in each line"},
85     {NULL,NULL,NULL}
86 };
87
88 /* List of BLOB TRAJECTORY POST PROCESSING modules: */
89 typedef struct DefModule_BlobTrackPostProc
90 {
91     CvBlobTrackPostProc* (*create)();
92     const char* nickname;
93     const char* description;
94 } DefModule_BlobTrackPostProc;
95
96 DefModule_BlobTrackPostProc BlobTrackPostProc_Modules[] =
97 {
98     {cvCreateModuleBlobTrackPostProcKalman,"Kalman","Kalman filtering of blob position and size"},
99     {NULL,"None","No post processing filter"},
100 //    {cvCreateModuleBlobTrackPostProcTimeAverRect,"TimeAverRect","Average by time using rectangle window"},
101 //    {cvCreateModuleBlobTrackPostProcTimeAverExp,"TimeAverExp","Average by time using exponential window"},
102     {NULL,NULL,NULL}
103 };
104
105 /* List of BLOB TRAJECTORY ANALYSIS modules: */
106 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisDetector();
107
108 typedef struct DefModule_BlobTrackAnalysis
109 {
110     CvBlobTrackAnalysis* (*create)();
111     const char* nickname;
112     const char* description;
113 } DefModule_BlobTrackAnalysis;
114
115 DefModule_BlobTrackAnalysis BlobTrackAnalysis_Modules[] =
116 {
117     {cvCreateModuleBlobTrackAnalysisHistPVS,"HistPVS","Histogram of 5D feature vector analysis (x,y,vx,vy,state)"},
118     {NULL,"None","No trajectory analiser"},
119     {cvCreateModuleBlobTrackAnalysisHistP,"HistP","Histogram of 2D feature vector analysis (x,y)"},
120     {cvCreateModuleBlobTrackAnalysisHistPV,"HistPV","Histogram of 4D feature vector analysis (x,y,vx,vy)"},
121     {cvCreateModuleBlobTrackAnalysisHistSS,"HistSS","Histogram of 4D feature vector analysis (startpos,endpos)"},
122     {cvCreateModuleBlobTrackAnalysisTrackDist,"TrackDist","Compare tracks directly"},
123     {cvCreateModuleBlobTrackAnalysisIOR,"IOR","Integrator (by OR operation) of several analysers "},
124     {NULL,NULL,NULL}
125 };
126
127 /* List of Blob Trajectory ANALYSIS modules: */
128 /*================= END MODULES DECRIPTION ===================================*/
129
130 /* Run pipeline on all frames: */
131 static int RunBlobTrackingAuto( CvCapture* pCap, CvBlobTrackerAuto* pTracker,char* fgavi_name = NULL, char* btavi_name = NULL )
132 {
133     int                     OneFrameProcess = 0;
134     int                     key;
135     int                     FrameNum = 0;
136     CvVideoWriter*          pFGAvi = NULL;
137     CvVideoWriter*          pBTAvi = NULL;
138
139     //cvNamedWindow( "FG", 0 );
140
141     /* Main loop: */
142     for( FrameNum=0; pCap && (key=cvWaitKey(OneFrameProcess?0:1))!=27;
143          FrameNum++)
144     {   /* Main loop: */
145         IplImage*   pImg  = NULL;
146         IplImage*   pMask = NULL;
147
148         if(key!=-1)
149         {
150             OneFrameProcess = 1;
151             if(key=='r')OneFrameProcess = 0;
152         }
153
154         pImg = cvQueryFrame(pCap);
155         if(pImg == NULL) break;
156
157
158         /* Process: */
159         pTracker->Process(pImg, pMask);
160
161         if(fgavi_name)
162         if(pTracker->GetFGMask())
163         {   /* Debug FG: */
164             IplImage*           pFG = pTracker->GetFGMask();
165             CvSize              S = cvSize(pFG->width,pFG->height);
166             static IplImage*    pI = NULL;
167
168             if(pI==NULL)pI = cvCreateImage(S,pFG->depth,3);
169             cvCvtColor( pFG, pI, CV_GRAY2BGR );
170
171             if(fgavi_name)
172             {   /* Save fg to avi file: */
173                 if(pFGAvi==NULL)
174                 {
175                     pFGAvi=cvCreateVideoWriter(
176                         fgavi_name,
177                         CV_FOURCC('x','v','i','d'),
178                         25,
179                         S );
180                 }
181                 cvWriteFrame( pFGAvi, pI );
182             }
183
184             if(pTracker->GetBlobNum()>0)
185             {   /* Draw detected blobs: */
186                 int i;
187                 for(i=pTracker->GetBlobNum();i>0;i--)
188                 {
189                     CvBlob* pB = pTracker->GetBlob(i-1);
190                     CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
191                     CvSize  s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB))), MAX(1,cvRound(CV_BLOB_RY(pB))));
192                     int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
193                     cvEllipse( pI,
194                         p,
195                         s,
196                         0, 0, 360,
197                         CV_RGB(c,255-c,0), cvRound(1+(3*c)/255) );
198                 }   /* Next blob: */;
199             }
200
201             cvNamedWindow( "FG",0);
202             cvShowImage( "FG",pI);
203         }   /* Debug FG. */
204
205
206         /* Draw debug info: */
207         if(pImg)
208         {   /* Draw all information about test sequence: */
209             char        str[1024];
210             int         line_type = CV_AA;   // Change it to 8 to see non-antialiased graphics.
211             CvFont      font;
212             int         i;
213             IplImage*   pI = cvCloneImage(pImg);
214
215             cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 0.7, 0.7, 0, 1, line_type );
216
217             for(i=pTracker->GetBlobNum(); i>0; i--)
218             {
219                 CvSize  TextSize;
220                 CvBlob* pB = pTracker->GetBlob(i-1);
221                 CvPoint p = cvPoint(cvRound(pB->x*256),cvRound(pB->y*256));
222                 CvSize  s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB)*256)), MAX(1,cvRound(CV_BLOB_RY(pB)*256)));
223                 int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
224
225                 cvEllipse( pI,
226                     p,
227                     s,
228                     0, 0, 360,
229                     CV_RGB(c,255-c,0), cvRound(1+(3*0)/255), CV_AA, 8 );
230
231                 p.x >>= 8;
232                 p.y >>= 8;
233                 s.width >>= 8;
234                 s.height >>= 8;
235                 sprintf(str,"%03d",CV_BLOB_ID(pB));
236                 cvGetTextSize( str, &font, &TextSize, NULL );
237                 p.y -= s.height;
238                 cvPutText( pI, str, p, &font, CV_RGB(0,255,255));
239                 {
240                     const char* pS = pTracker->GetStateDesc(CV_BLOB_ID(pB));
241
242                     if(pS)
243                     {
244                         char* pStr = MY_STRDUP(pS);
245                         char* pStrFree = pStr;
246
247                         while (pStr && strlen(pStr) > 0)
248                         {
249                             char* str_next = strchr(pStr,'\n');
250
251                             if(str_next)
252                             {
253                                 str_next[0] = 0;
254                                 str_next++;
255                             }
256
257                             p.y += TextSize.height+1;
258                             cvPutText( pI, pStr, p, &font, CV_RGB(0,255,255));
259                             pStr = str_next;
260                         }
261                         free(pStrFree);
262                     }
263                 }
264
265             }   /* Next blob. */;
266
267             cvNamedWindow( "Tracking", 0);
268             cvShowImage( "Tracking",pI );
269
270             if(btavi_name && pI)
271             {   /* Save to avi file: */
272                 CvSize      S = cvSize(pI->width,pI->height);
273                 if(pBTAvi==NULL)
274                 {
275                     pBTAvi=cvCreateVideoWriter(
276                         btavi_name,
277                         CV_FOURCC('x','v','i','d'),
278                         25,
279                         S );
280                 }
281                 cvWriteFrame( pBTAvi, pI );
282             }
283
284             cvReleaseImage(&pI);
285         }   /* Draw all information about test sequence. */
286     }   /*  Main loop. */
287
288     if(pFGAvi)cvReleaseVideoWriter( &pFGAvi );
289     if(pBTAvi)cvReleaseVideoWriter( &pBTAvi );
290     return 0;
291 }   /* RunBlobTrackingAuto */
292
293 /* Read parameters from command line
294  * and transfer to specified module:
295  */
296 static void set_params(int argc, char* argv[], CvVSModule* pM, const char* prefix, const char* module)
297 {
298     int prefix_len = (int)strlen(prefix);
299     int i;
300     for(i=0; i<argc; ++i)
301     {
302         int j;
303         char* ptr_eq = NULL;
304         int   cmd_param_len=0;
305         char* cmd = argv[i];
306         if(MY_STRNICMP(prefix,cmd,prefix_len)!=0) continue;
307         cmd += prefix_len;
308         if(cmd[0]!=':')continue;
309         cmd++;
310
311         ptr_eq = strchr(cmd,'=');
312         if(ptr_eq)
313             cmd_param_len = (int)(ptr_eq-cmd);
314
315         for(j=0; ; ++j)
316         {
317             int     param_len;
318             const char*   param = pM->GetParamName(j);
319             if(param==NULL) break;
320             param_len = (int)strlen(param);
321             if(cmd_param_len!=param_len) continue;
322             if(MY_STRNICMP(param,cmd,param_len)!=0) continue;
323             cmd+=param_len;
324             if(cmd[0]!='=')continue;
325             cmd++;
326             pM->SetParamStr(param,cmd);
327             printf("%s:%s param set to %g\n",module,param,pM->GetParam(param));
328         }
329     }
330
331     pM->ParamUpdate();
332
333 }   /* set_params */
334
335 /* Print all parameter values for given module: */
336 static void print_params(CvVSModule* pM, const char* module, const char* log_name)
337 {
338     FILE* log = log_name?fopen(log_name,"at"):NULL;
339     int i;
340     if(pM->GetParamName(0) == NULL ) return;
341
342
343     printf("%s(%s) module parameters:\n",module,pM->GetNickName());
344     if(log)
345         fprintf(log,"%s(%s) module parameters:\n",module,pM->GetNickName());
346
347     for (i=0; ; ++i)
348     {
349         const char*   param = pM->GetParamName(i);
350         const char*   str = param?pM->GetParamStr(param):NULL;
351         if(param == NULL)break;
352         if(str)
353         {
354             printf("  %s: %s\n",param,str);
355             if(log)
356                 fprintf(log,"  %s: %s\n",param,str);
357         }
358         else
359         {
360             printf("  %s: %g\n",param,pM->GetParam(param));
361             if(log)
362                 fprintf(log,"  %s: %g\n",param,pM->GetParam(param));
363         }
364     }
365
366     if(log) fclose(log);
367
368 }   /* print_params */
369
370 int main(int argc, char* argv[])
371 {   /* Main function: */
372     CvCapture*                  pCap = NULL;
373     CvBlobTrackerAutoParam1     param = {0,0,0,0,0,0,0,0};
374     CvBlobTrackerAuto*          pTracker = NULL;
375
376     //float       scale = 1;
377     const char* scale_name = NULL;
378     char*       yml_name = NULL;
379     char**      yml_video_names = NULL;
380     int         yml_video_num = 0;
381     char*       avi_name = NULL;
382     const char* fg_name = NULL;
383     char*       fgavi_name = NULL;
384     char*       btavi_name = NULL;
385     const char* bd_name = NULL;
386     const char* bt_name = NULL;
387     const char* btgen_name = NULL;
388     const char* btpp_name = NULL;
389     const char* bta_name = NULL;
390     char*       bta_data_name = NULL;
391     char*       track_name = NULL;
392     //char*       comment_name = NULL;
393     char*       FGTrainFrames = NULL;
394     char*       log_name = NULL;
395     char*       savestate_name = NULL;
396     char*       loadstate_name = NULL;
397     const char* bt_corr = NULL;
398     DefModule_FGDetector*           pFGModule = NULL;
399     DefModule_BlobDetector*         pBDModule = NULL;
400     DefModule_BlobTracker*          pBTModule = NULL;
401     DefModule_BlobTrackPostProc*    pBTPostProcModule = NULL;
402     DefModule_BlobTrackGen*         pBTGenModule = NULL;
403     DefModule_BlobTrackAnalysis*    pBTAnalysisModule = NULL;
404
405     cvInitSystem(argc, argv);
406
407     if(argc < 2)
408     {   /* Print help: */
409         int i;
410         printf("blobtrack [fg=<fg_name>] [bd=<bd_name>]\n"
411             "          [bt=<bt_name>] [btpp=<btpp_name>]\n"
412             "          [bta=<bta_name>\n"
413             "          [bta_data=<bta_data_name>\n"
414             "          [bt_corr=<bt_corr_way>]\n"
415             "          [btgen=<btgen_name>]\n"
416             "          [track=<track_file_name>]\n"
417             "          [scale=<scale val>] [noise=<noise_name>] [IVar=<IVar_name>]\n"
418             "          [FGTrainFrames=<FGTrainFrames>]\n"
419             "          [btavi=<avi output>] [fgavi=<avi output on FG>]\n"
420             "          <avi_file>\n");
421
422         printf("  <bt_corr_way> is the method of blob position correction for the \"Blob Tracking\" module\n"
423             "     <bt_corr_way>=none,PostProcRes\n"
424             "  <FGTrainFrames> is number of frames for FG training\n"
425             "  <track_file_name> is file name for save tracked trajectories\n"
426             "  <bta_data> is file name for data base of trajectory analysis module\n"
427             "  <avi_file> is file name of avi to process by BlobTrackerAuto\n");
428
429         puts("\nModules:");
430 #define PR(_name,_m,_mt)\
431         printf("<%s> is \"%s\" module name and can be:\n",_name,_mt);\
432         for(i=0; _m[i].nickname; ++i)\
433         {\
434             printf("  %d. %s",i+1,_m[i].nickname);\
435             if(_m[i].description)printf(" - %s",_m[i].description);\
436             printf("\n");\
437         }
438
439         PR("fg_name",FGDetector_Modules,"FG/BG Detection");
440         PR("bd_name",BlobDetector_Modules,"Blob Entrance Detection");
441         PR("bt_name",BlobTracker_Modules,"Blob Tracking");
442         PR("btpp_name",BlobTrackPostProc_Modules, "Blob Trajectory Post Processing");
443         PR("btgen_name",BlobTrackGen_Modules, "Blob Trajectory Generation");
444         PR("bta_name",BlobTrackAnalysis_Modules, "Blob Trajectory Analysis");
445 #undef PR
446         return 0;
447     }   /* Print help. */
448
449     {   /* Parse arguments: */
450         int i;
451         for(i=1; i<argc; ++i)
452         {
453             int bParsed = 0;
454             size_t len = strlen(argv[i]);
455 #define RO(_n1,_n2) if(strncmp(argv[i],_n1,strlen(_n1))==0) {_n2 = argv[i]+strlen(_n1);bParsed=1;};
456             RO("fg=",fg_name);
457             RO("fgavi=",fgavi_name);
458             RO("btavi=",btavi_name);
459             RO("bd=",bd_name);
460             RO("bt=",bt_name);
461             RO("bt_corr=",bt_corr);
462             RO("btpp=",btpp_name);
463             RO("bta=",bta_name);
464             RO("bta_data=",bta_data_name);
465             RO("btgen=",btgen_name);
466             RO("track=",track_name);
467             //RO("comment=",comment_name);
468             RO("FGTrainFrames=",FGTrainFrames);
469             RO("log=",log_name);
470             RO("savestate=",savestate_name);
471             RO("loadstate=",loadstate_name);
472 #undef RO
473             {
474                 char* ext = argv[i] + len-4;
475                 if( strrchr(argv[i],'=') == NULL &&
476                     !bParsed &&
477                     (len>3 && (MY_STRICMP(ext,".avi") == 0 )))
478                 {
479                     avi_name = argv[i];
480                     break;
481                 }
482             }   /* Next argument. */
483         }
484     }   /* Parse arguments. */
485
486     if(track_name)
487     {   /* Set Trajectory Generator module: */
488         int i;
489         if(!btgen_name)btgen_name=BlobTrackGen_Modules[0].nickname;
490
491         for(i=0; BlobTrackGen_Modules[i].nickname; ++i)
492         {
493             if(MY_STRICMP(BlobTrackGen_Modules[i].nickname,btgen_name)==0)
494                 pBTGenModule = BlobTrackGen_Modules + i;
495         }
496     }   /* Set Trajectory Generato module. */
497
498     /* Initialize postprocessing module if tracker
499      * correction by postprocessing is required.
500      */
501     if(bt_corr && MY_STRICMP(bt_corr,"PostProcRes")!=0 && !btpp_name)
502     {
503         btpp_name = bt_corr;
504         if(MY_STRICMP(btpp_name,"none")!=0)bt_corr = "PostProcRes";
505     }
506
507     {   /* Set default parameters for one processing: */
508         if(!bt_corr) bt_corr = "none";
509         if(!fg_name) fg_name = FGDetector_Modules[0].nickname;
510         if(!bd_name) bd_name = BlobDetector_Modules[0].nickname;
511         if(!bt_name) bt_name = BlobTracker_Modules[0].nickname;
512         if(!btpp_name) btpp_name = BlobTrackPostProc_Modules[0].nickname;
513         if(!bta_name) bta_name = BlobTrackAnalysis_Modules[0].nickname;
514         if(!scale_name) scale_name = "1";
515     }
516
517 //    if(scale_name)
518   //      scale = (float)atof(scale_name);
519
520     for(pFGModule=FGDetector_Modules; pFGModule->nickname; ++pFGModule)
521         if( fg_name && MY_STRICMP(fg_name,pFGModule->nickname)==0 ) break;
522
523     for(pBDModule=BlobDetector_Modules; pBDModule->nickname; ++pBDModule)
524         if( bd_name && MY_STRICMP(bd_name,pBDModule->nickname)==0 ) break;
525
526     for(pBTModule=BlobTracker_Modules; pBTModule->nickname; ++pBTModule)
527         if( bt_name && MY_STRICMP(bt_name,pBTModule->nickname)==0 ) break;
528
529     for(pBTPostProcModule=BlobTrackPostProc_Modules; pBTPostProcModule->nickname; ++pBTPostProcModule)
530         if( btpp_name && MY_STRICMP(btpp_name,pBTPostProcModule->nickname)==0 ) break;
531
532     for(pBTAnalysisModule=BlobTrackAnalysis_Modules; pBTAnalysisModule->nickname; ++pBTAnalysisModule)
533         if( bta_name && MY_STRICMP(bta_name,pBTAnalysisModule->nickname)==0 ) break;
534
535     /* Create source video: */
536     if(avi_name)
537         pCap = cvCaptureFromFile(avi_name);
538
539     if(pCap==NULL)
540     {
541         printf("Can't open %s file\n",avi_name);
542         return -1;
543     }
544
545
546     {   /* Display parameters: */
547         int i;
548         FILE* log = log_name?fopen(log_name,"at"):NULL;
549         if(log)
550         {   /* Print to log file: */
551             fprintf(log,"\n=== Blob Tracking pipline in processing mode===\n");
552             if(avi_name)
553             {
554                 fprintf(log,"AVIFile: %s\n",avi_name);
555             }
556             fprintf(log,"FGDetector:   %s\n", pFGModule->nickname);
557             fprintf(log,"BlobDetector: %s\n", pBDModule->nickname);
558             fprintf(log,"BlobTracker:  %s\n", pBTModule->nickname);
559             fprintf(log,"BlobTrackPostProc:  %s\n", pBTPostProcModule->nickname);
560             fprintf(log,"BlobCorrection:  %s\n", bt_corr);
561
562             fprintf(log,"Blob Trajectory Generator:  %s (%s)\n",
563                 pBTGenModule?pBTGenModule->nickname:"None",
564                 track_name?track_name:"none");
565
566             fprintf(log,"BlobTrackAnalysis:  %s\n", pBTAnalysisModule->nickname);
567             fclose(log);
568         }
569
570         printf("\n=== Blob Tracking pipline in %s mode===\n","processing");
571         if(yml_name)
572         {
573             printf("ConfigFile: %s\n",yml_name);
574             printf("BG: %s\n",yml_video_names[0]);
575             printf("FG: ");
576             for(i=1;i<(yml_video_num);++i){printf("%s",yml_video_names[i]);if((i+1)<yml_video_num)printf("|");};
577             printf("\n");
578         }
579         if(avi_name)
580         {
581             printf("AVIFile: %s\n",avi_name);
582         }
583         printf("FGDetector:   %s\n", pFGModule->nickname);
584         printf("BlobDetector: %s\n", pBDModule->nickname);
585         printf("BlobTracker:  %s\n", pBTModule->nickname);
586         printf("BlobTrackPostProc:  %s\n", pBTPostProcModule->nickname);
587         printf("BlobCorrection:  %s\n", bt_corr);
588
589         printf("Blob Trajectory Generator:  %s (%s)\n",
590             pBTGenModule?pBTGenModule->nickname:"None",
591             track_name?track_name:"none");
592
593         printf("BlobTrackAnalysis:  %s\n", pBTAnalysisModule->nickname);
594
595     }   /* Display parameters. */
596
597     {   /* Create autotracker module and its components: */
598         param.FGTrainFrames = FGTrainFrames?atoi(FGTrainFrames):0;
599
600         /* Create FG Detection module: */
601         param.pFG = pFGModule->create();
602         if(!param.pFG)
603             puts("Can not create FGDetector module");
604         param.pFG->SetNickName(pFGModule->nickname);
605         set_params(argc, argv, param.pFG, "fg", pFGModule->nickname);
606
607         /* Create Blob Entrance Detection module: */
608         param.pBD = pBDModule->create();
609         if(!param.pBD)
610             puts("Can not create BlobDetector module");
611         param.pBD->SetNickName(pBDModule->nickname);
612         set_params(argc, argv, param.pBD, "bd", pBDModule->nickname);
613
614         /* Create blob tracker module: */
615         param.pBT = pBTModule->create();
616         if(!param.pBT)
617             puts("Can not create BlobTracker module");
618         param.pBT->SetNickName(pBTModule->nickname);
619         set_params(argc, argv, param.pBT, "bt", pBTModule->nickname);
620
621         /* Create blob trajectory generation module: */
622         param.pBTGen = NULL;
623         if(pBTGenModule && track_name && pBTGenModule->create)
624         {
625             param.pBTGen = pBTGenModule->create();
626             param.pBTGen->SetFileName(track_name);
627         }
628         if(param.pBTGen)
629         {
630             param.pBTGen->SetNickName(pBTGenModule->nickname);
631             set_params(argc, argv, param.pBTGen, "btgen", pBTGenModule->nickname);
632         }
633
634         /* Create blob trajectory post processing module: */
635         param.pBTPP = NULL;
636         if(pBTPostProcModule && pBTPostProcModule->create)
637         {
638             param.pBTPP = pBTPostProcModule->create();
639         }
640         if(param.pBTPP)
641         {
642             param.pBTPP->SetNickName(pBTPostProcModule->nickname);
643             set_params(argc, argv, param.pBTPP, "btpp", pBTPostProcModule->nickname);
644         }
645
646         param.UsePPData = (bt_corr && MY_STRICMP(bt_corr,"PostProcRes")==0);
647
648         /* Create blob trajectory analysis module: */
649         param.pBTA = NULL;
650         if(pBTAnalysisModule && pBTAnalysisModule->create)
651         {
652             param.pBTA = pBTAnalysisModule->create();
653             param.pBTA->SetFileName(bta_data_name);
654         }
655         if(param.pBTA)
656         {
657             param.pBTA->SetNickName(pBTAnalysisModule->nickname);
658             set_params(argc, argv, param.pBTA, "bta", pBTAnalysisModule->nickname);
659         }
660
661         /* Create whole pipline: */
662         pTracker = cvCreateBlobTrackerAuto1(&param);
663         if(!pTracker)
664             puts("Can not create BlobTrackerAuto");
665     }
666
667     {   /* Load states of each module from state file: */
668         CvFileStorage* fs = NULL;
669         if(loadstate_name)
670             fs=cvOpenFileStorage(loadstate_name,NULL,CV_STORAGE_READ);
671         if(fs)
672         {
673             printf("Load states for modules...\n");
674             if(param.pBT)
675             {
676                 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTracker");
677                 param.pBT->LoadState(fs,fn);
678             }
679
680             if(param.pBTA)
681             {
682                 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackAnalyser");
683                 param.pBTA->LoadState(fs,fn);
684             }
685
686             if(pTracker)
687             {
688                 CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackerAuto");
689                 pTracker->LoadState(fs,fn);
690             }
691
692             cvReleaseFileStorage(&fs);
693             printf("... Modules states loaded\n");
694         }
695     }   /* Load states of each module. */
696
697     {   /* Print module parameters: */
698         struct DefMMM
699         {
700             CvVSModule* pM;
701             const char* name;
702         } Modules[] = {
703             {(CvVSModule*)param.pFG,"FGdetector"},
704             {(CvVSModule*)param.pBD,"BlobDetector"},
705             {(CvVSModule*)param.pBT,"BlobTracker"},
706             {(CvVSModule*)param.pBTGen,"TrackGen"},
707             {(CvVSModule*)param.pBTPP,"PostProcessing"},
708             {(CvVSModule*)param.pBTA,"TrackAnalysis"},
709             {NULL,NULL}
710         };
711         int     i;
712         for(i=0; Modules[i].name; ++i)
713         {
714             if(Modules[i].pM)
715                 print_params(Modules[i].pM,Modules[i].name,log_name);
716         }
717     }   /* Print module parameters. */
718
719     /* Run pipeline: */
720     RunBlobTrackingAuto( pCap, pTracker, fgavi_name, btavi_name );
721
722     {   /* Save state and release modules: */
723         CvFileStorage* fs = NULL;
724         if(savestate_name)
725         {
726             fs=cvOpenFileStorage(savestate_name,NULL,CV_STORAGE_WRITE);
727         }
728         if(fs)
729         {
730             cvStartWriteStruct(fs,"BlobTracker",CV_NODE_MAP);
731             if(param.pBT)param.pBT->SaveState(fs);
732             cvEndWriteStruct(fs);
733             cvStartWriteStruct(fs,"BlobTrackerAuto",CV_NODE_MAP);
734             if(pTracker)pTracker->SaveState(fs);
735             cvEndWriteStruct(fs);
736             cvStartWriteStruct(fs,"BlobTrackAnalyser",CV_NODE_MAP);
737             if(param.pBTA)param.pBTA->SaveState(fs);
738             cvEndWriteStruct(fs);
739             cvReleaseFileStorage(&fs);
740         }
741         if(param.pBT)cvReleaseBlobTracker(&param.pBT);
742         if(param.pBD)cvReleaseBlobDetector(&param.pBD);
743         if(param.pBTGen)cvReleaseBlobTrackGen(&param.pBTGen);
744         if(param.pBTA)cvReleaseBlobTrackAnalysis(&param.pBTA);
745         if(param.pFG)cvReleaseFGDetector(&param.pFG);
746         if(pTracker)cvReleaseBlobTrackerAuto(&pTracker);
747
748     }   /* Save state and release modules. */
749
750     if(pCap)
751         cvReleaseCapture(&pCap);
752
753     return 0;
754
755 }   /* main() */