1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
12 // Copyright (C) 2000, Intel Corporation, rights reserved.
13 // Third party copyrights are property of their respective owners.
15 // Redistribution and use in source and binary forms, with or without modification,
16 // are permitted provided that the following conditions are met:
18 // * Redistribution's of source code must retain the above copyright notice,
19 // this list of conditions and the following disclaimer.
21 // * Redistribution's in binary form must reproduce the above copyright notice,
22 // this list of conditions and the following disclaimer in the documentation
23 // and/or other materials provided with the distribution.
25 // * The name of Intel Corporation may not be used to endorse or promote products
26 // derived from this software without specific prior written permission.
28 // This software is provided by the copyright holders and contributors "as is" and
29 // any express or implied warranties, including, but not limited to, the implied
30 // warranties of merchantability and fitness for a particular purpose are disclaimed.
31 // In no event shall the Intel Corporation or contributors be liable for any direct,
32 // indirect, incidental, special, exemplary, or consequential damages
33 // (including, but not limited to, procurement of substitute goods or services;
34 // loss of use, data, or profits; or business interruption) however caused
35 // and on any theory of liability, whether in contract, strict liability,
36 // or tort (including negligence or otherwise) arising in any way out of
37 // the use of this software, even if advised of the possibility of such damage.
42 This file contain simple implementation of BlobTrackerAuto virtual interface
43 This module just connected other low level 3 modules
44 (foreground estimator + BlobDetector + BlobTracker)
45 and some simple code to detect "lost tracking"
46 The track is lost when integral of foreground mask image by blob area has low value
51 /* list of Blob Detection modules */
52 CvBlobDetector* cvCreateBlobDetectorSimple();
54 /* get frequency for each module time working estimation */
55 static double FREQ = 1000*cvGetTickFrequency();
59 #define TIME_BEGIN() \
61 static double _TimeSum = 0;\
62 static int _Count = 0;\
63 static int _CountBlob = 0;\
64 int64 _TickCount = cvGetTickCount();\
66 #define TIME_END(_name_,_BlobNum_) \
68 _CountBlob+=_BlobNum_;\
69 _TimeSum += (cvGetTickCount()-_TickCount)/FREQ;\
70 if(m_TimesFile)if(_Count%COUNTNUM==0)\
72 FILE* out = fopen(m_TimesFile,"at");\
75 fprintf(out,"ForFrame Frame: %d %s %f on %f blobs\n",_Count,_name_, _TimeSum/COUNTNUM,((float)_CountBlob)/COUNTNUM);\
76 if(_CountBlob>0)fprintf(out,"ForBlob Frame: %d %s - %f\n",_Count,_name_, _TimeSum/_CountBlob);\
85 #define TIME_END(_name_)
88 /* special extended blob structure for auto blob tracking */
89 typedef struct CvBlobTrackAuto
95 class CvBlobTrackerAuto1: public CvBlobTrackerAuto
98 CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param);
99 ~CvBlobTrackerAuto1();
100 CvBlob* GetBlob(int index){return m_BlobList.GetBlob(index);};
101 CvBlob* GetBlobByID(int ID){return m_BlobList.GetBlobByID(ID);};
102 int GetBlobNum(){return m_BlobList.GetBlobNum();};
103 virtual IplImage* GetFGMask(){return m_pFGMask;};
104 float GetState(int BlobID){return m_pBTA?m_pBTA->GetState(BlobID):0;};
105 char* GetStateDesc(int BlobID){return m_pBTA?m_pBTA->GetStateDesc(BlobID):NULL;};
106 /* return 0 if trajectory is normal
107 return >0 if trajectory abnormal */
108 void Process(IplImage* pImg, IplImage* pMask = NULL);
109 void Release(){delete this;};
113 CvFGDetector* m_pFG; /* pointer to foreground mask detector modelu */
114 CvBlobTracker* m_pBT; /* pointer to Blob tracker module */
117 CvBlobDetector* m_pBD; /* pointer to Blob detector module */
119 CvBlobTrackGen* m_pBTGen;
120 CvBlobTrackPostProc* m_pBTPostProc;
122 CvBlobTrackAnalysis* m_pBTA; /* blob trajectory analyser */
123 CvBlobSeq m_BlobList;
128 virtual void SaveState(CvFileStorage* fs)
130 cvWriteInt(fs,"FrameCount",m_FrameCount);
131 cvWriteInt(fs,"NextBlobID",m_NextBlobID);
132 m_BlobList.Write(fs,"BlobList");
134 virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
136 CvFileNode* BlobListNode = cvGetFileNodeByName(fs,node,"BlobList");
137 m_FrameCount = cvReadIntByName(fs,node, "FrameCount", m_FrameCount);
138 m_NextBlobID = cvReadIntByName(fs,node, "NextBlobID", m_NextBlobID);
141 m_BlobList.Load(fs,BlobListNode);
146 /* Auto Blob tracker creater (sole interface function for this file) */
147 CvBlobTrackerAuto* cvCreateBlobTrackerAuto1(CvBlobTrackerAutoParam1* param)
149 return (CvBlobTrackerAuto*)new CvBlobTrackerAuto1(param);
152 /* Constructor of auto blob tracker*/
153 CvBlobTrackerAuto1::CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param):m_BlobList(sizeof(CvBlobTrackAuto))
155 m_BlobList.AddFormat("i");
157 AddParam("TimesFile",&m_TimesFile);
163 m_FGTrainFrames = param?param->FGTrainFrames:0;
164 m_pFG = param?param->pFG:0;
167 m_pBD = param?param->pBD:NULL;
169 m_pBT = param?param->pBT:NULL;;
170 m_BTReal = m_pBT?m_pBT->IsModuleName("BlobTrackerReal"):0;
172 m_pBTGen = param?param->pBTGen:NULL;
174 m_pBTA = param?param->pBTA:NULL;
176 m_pBTPostProc = param?param->pBTPP:NULL;
177 m_UsePPData = param?param->UsePPData:0;
179 /* create default sub modules */
182 m_pBD = cvCreateBlobDetectorSimple();
187 m_pBT = cvCreateBlobTrackerMS();
191 }/* CvBlobTrackerAuto1::CvBlobTrackerAuto1 */
193 /* Destructor of auto blob tracker */
194 CvBlobTrackerAuto1::~CvBlobTrackerAuto1()
196 if(m_BDDel)m_pBD->Release();
197 if(m_BTDel)m_pBT->Release();
198 }/* Destructor of auto blob tracker */
200 void CvBlobTrackerAuto1::Process(IplImage* pImg, IplImage* pMask)
204 IplImage* pFG = pMask;
206 /* increase frame counter */
211 static int64 TickCount = cvGetTickCount();
212 static double TimeSum = 0;
213 static int Count = 0;
219 FILE* out = fopen(m_TimesFile,"at");
221 TickCount = cvGetTickCount()-TickCount;
222 Time = TickCount/FREQ;
223 if(out){fprintf(out,"- %sFrame: %d ALL_TIME - %f\n",ctime( <ime ),Count,Time/1000);fclose(out);}
226 TickCount = cvGetTickCount();
230 /* update BG model */
233 {/* if FG detector is needed */
234 m_pFG->Process(pImg);
235 pFG = m_pFG->GetMask();
236 }/* if FG detector is needed */
237 TIME_END("FGDetector",-1)
238 m_pFGMask = pFG; /* for external use */
240 /*if(m_pFG && m_pFG->GetParam("DebugWnd") == 1)
241 {// debug foreground result
242 IplImage *pFG = m_pFG->GetMask();
245 cvNamedWindow("FG",0);
246 cvShowImage("FG", pFG);
255 m_pBT->Process(pImg, pFG);
256 for(i=m_BlobList.GetBlobNum();i>0;--i)
257 {/* update data of tracked blob list */
258 CvBlob* pB = m_BlobList.GetBlob(i-1);
259 int BlobID = CV_BLOB_ID(pB);
260 int i = m_pBT->GetBlobIndexByID(BlobID);
261 m_pBT->ProcessBlob(i, pB, pImg, pFG);
264 CurBlobNum = m_pBT->GetBlobNum();
266 TIME_END("BlobTracker",CurBlobNum)
268 /* this part should be removed */
269 if(m_BTReal && m_pBT)
270 {/* update blob list (detect new blob for real blob tracker )*/
272 for(i=m_pBT->GetBlobNum();i>0;--i)
273 {/* update data of tracked blob list */
274 CvBlob* pB = m_pBT->GetBlob(i-1);
275 if(pB && m_BlobList.GetBlobByID(CV_BLOB_ID(pB)) == NULL )
277 CvBlobTrackAuto NewB;
280 m_BlobList.AddBlob((CvBlob*)&NewB);
284 for(i=m_BlobList.GetBlobNum();i>0;--i)
285 {/* update data of tracked blob list */
286 CvBlob* pB = m_BlobList.GetBlob(i-1);
287 if(pB && m_pBT->GetBlobByID(CV_BLOB_ID(pB)) == NULL )
289 m_BlobList.DelBlob(i-1);
292 }/* update blob list */
297 {/* post processing module */
299 for(i=m_BlobList.GetBlobNum();i>0;--i)
300 {/* update data of tracked blob list */
301 CvBlob* pB = m_BlobList.GetBlob(i-1);
302 m_pBTPostProc->AddBlob(pB);
304 m_pBTPostProc->Process();
306 for(i=m_BlobList.GetBlobNum();i>0;--i)
307 {/* update data of tracked blob list */
308 CvBlob* pB = m_BlobList.GetBlob(i-1);
309 int BlobID = CV_BLOB_ID(pB);
310 CvBlob* pBN = m_pBTPostProc->GetBlobByID(BlobID);
312 if(pBN && m_UsePPData && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
313 { /* set new data for tracker */
314 m_pBT->SetBlobByID(BlobID, pBN );
318 {/* update blob list by result from postprocessing */
322 }/* post processing module */
323 TIME_END("PostProcessing",CurBlobNum)
325 /* Blob deleter (experimental and simple)*/
330 if(!m_BTReal)for(i=m_BlobList.GetBlobNum();i>0;--i)
331 {/* check all blobs from list */
332 CvBlobTrackAuto* pB = (CvBlobTrackAuto*)(m_BlobList.GetBlob(i-1));
336 CvRect r = CV_BLOB_RECT(pB);
339 double area = CV_BLOB_WX(pB)*CV_BLOB_WY(pB);
340 if(r.x < 0){r.width += r.x;r.x = 0;}
341 if(r.y < 0){r.height += r.y;r.y = 0;}
342 if(r.x+r.width>=w){r.width = w-r.x-1;}
343 if(r.y+r.height>=h){r.height = h-r.y-1;}
345 if(r.width > 4 && r.height > 4 && r.x < w && r.y < h &&
346 r.x >=0 && r.y >=0 &&
347 r.x+r.width < w && r.y+r.height < h && area > 0)
349 aver = cvSum(cvGetSubRect(pFG,&mat,r)).val[0] / area;
350 /* if mask in blob area exists then its blob OK*/
351 if(aver > 0.1*255)Good = 1;
368 /* check error count */
369 for(i=0;i<m_BlobList.GetBlobNum();++i)
371 CvBlobTrackAuto* pB = (CvBlobTrackAuto*)m_BlobList.GetBlob(i);
373 {/* delete such object */
375 m_pBT->DelBlobByID(CV_BLOB_ID(pB));
376 /* from local list */
377 m_BlobList.DelBlob(i);
380 }/* check error count for next blob */
382 TIME_END("BlobDeleter",m_BlobList.GetBlobNum())
387 m_pBT->Update(pImg, pFG);
388 TIME_END("BlobTrackerUpdate",CurBlobNum)
390 /* detect new blob */
392 if(!m_BTReal && m_pBD && pFG && (m_FrameCount > m_FGTrainFrames) )
393 {/* detect new blob */
394 static CvBlobSeq NewBlobList;
395 CvBlobTrackAuto NewB;
399 if(m_pBD->DetectNewBlob(pImg, pFG, &NewBlobList, &m_BlobList))
400 {/* add new blob to tracker and blob list */
402 IplImage* pMask = pFG;
404 /*if(0)if(NewBlobList.GetBlobNum()>0 && pFG )
405 {// erode FG mask (only for FG_0 and MS1||MS2)
406 pMask = cvCloneImage(pFG);
407 cvErode(pFG,pMask,NULL,2);
410 for(i=0;i<NewBlobList.GetBlobNum();++i)
412 CvBlob* pBN = NewBlobList.GetBlob(i);
413 pBN->ID = m_NextBlobID;
414 if(pBN && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
416 CvBlob* pB = m_pBT->AddBlob(pBN, pImg, pMask );
421 m_BlobList.AddBlob((CvBlob*)&NewB);
425 }/* add next blob from list of detected blob */
427 if(pMask != pFG) cvReleaseImage(&pMask);
429 }/* create and add new blobs and trackers */
430 }/* detect new blob */
431 TIME_END("BlobDetector",-1)
435 {/* run tracj generator */
436 for(i=m_BlobList.GetBlobNum();i>0;--i)
437 {/* update data of tracked blob list */
438 CvBlob* pB = m_BlobList.GetBlob(i-1);
439 m_pBTGen->AddBlob(pB);
441 m_pBTGen->Process(pImg, pFG);
442 }/* run tracj generator */
443 TIME_END("TrajectoryGeneration",-1)
447 {/* trajectory analysis module */
449 for(i=m_BlobList.GetBlobNum();i>0;i--)
450 m_pBTA->AddBlob(m_BlobList.GetBlob(i-1));
451 m_pBTA->Process(pImg, pFG);
452 }/* trajectory analysis module */
453 TIME_END("TrackAnalysis",m_BlobList.GetBlobNum())
455 }/* CvBlobTrackerAuto1::Process */