00e4905ccaa77b642a11edb8b3dad7df4be01ef1
[platform/upstream/opencv.git] / modules / legacy / src / blobtrack.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The names of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "precomp.hpp"
44
45 //////////////////////////// CvVSModule /////////////////////////////
46
47 CvVSModule::CvVSModule()
48 {
49     m_pNickName = NULL;
50     m_pParamList = NULL;
51     m_pModuleTypeName = NULL;
52     m_pModuleName = NULL;
53     m_Wnd = 0;
54     AddParam("DebugWnd",&m_Wnd);
55 }
56
57 CvVSModule::~CvVSModule()
58 {
59     CvDefParam* p = m_pParamList;
60     for(;p;)
61     {
62         CvDefParam* pf = p;
63         p=p->next;
64         FreeParam(&pf);
65     }
66     m_pParamList=NULL;
67     if(m_pModuleTypeName)free(m_pModuleTypeName);
68     if(m_pModuleName)free(m_pModuleName);
69 }
70
71 void    CvVSModule::FreeParam(CvDefParam** pp)
72 {
73     CvDefParam* p = pp[0];
74     if(p->Str)free(p->Str);
75     if(p->pName)free(p->pName);
76     if(p->pComment)free(p->pComment);
77     cvFree(pp);
78 }
79
80 CvDefParam* CvVSModule::NewParam(const char* name)
81 {
82     CvDefParam* pNew = (CvDefParam*)cvAlloc(sizeof(CvDefParam));
83     memset(pNew,0,sizeof(CvDefParam));
84     pNew->pName = strdup(name);
85     if(m_pParamList==NULL)
86     {
87         m_pParamList = pNew;
88     }
89     else
90     {
91         CvDefParam* p = m_pParamList;
92         for(;p->next;p=p->next) ;
93         p->next = pNew;
94     }
95     return pNew;
96 }
97
98 CvDefParam* CvVSModule::GetParamPtr(int index)
99 {
100     CvDefParam* p = m_pParamList;
101     for(;index>0 && p;index--,p=p->next) ;
102     return p;
103 }
104
105 CvDefParam* CvVSModule::GetParamPtr(const char* name)
106 {
107     CvDefParam* p = m_pParamList;
108     for(;p;p=p->next)
109     {
110         if(cv_stricmp(p->pName,name)==0) break;
111     }
112     return p;
113 }
114
115 int  CvVSModule::IsParam(const char* name)
116 {
117     return GetParamPtr(name)?1:0;
118 }
119
120 void CvVSModule::AddParam(const char* name, double* pAddr)
121 {
122     NewParam(name)->pDouble = pAddr;
123 }
124
125 void CvVSModule::AddParam(const char* name, float* pAddr)
126 {
127     NewParam(name)->pFloat=pAddr;
128 }
129
130 void CvVSModule::AddParam(const char* name, int* pAddr)
131 {
132     NewParam(name)->pInt=pAddr;
133 }
134
135 void CvVSModule::AddParam(const char* name, const char** pAddr)
136 {
137     CvDefParam* pP = NewParam(name);
138     const char* p = pAddr?pAddr[0]:NULL;
139     pP->pStr = pAddr?(char**)pAddr:&(pP->Str);
140     if(p)
141     {
142         pP->Str = strdup(p);
143         pP->pStr[0] = pP->Str;
144     }
145 }
146
147 void CvVSModule::AddParam(const char* name)
148 {
149     CvDefParam* p = NewParam(name);
150     p->pDouble = &p->Double;
151 }
152
153 void CvVSModule::CommentParam(const char* name, const char* pComment)
154 {
155     CvDefParam* p = GetParamPtr(name);
156     if(p)p->pComment = pComment ? strdup(pComment) : 0;
157 }
158
159 void CvVSModule::SetTypeName(const char* name){m_pModuleTypeName = strdup(name);}
160
161 void CvVSModule::SetModuleName(const char* name){m_pModuleName = strdup(name);}
162
163 void CvVSModule::DelParam(const char* name)
164 {
165     CvDefParam* p = m_pParamList;
166     CvDefParam* pPrev = NULL;
167     for(;p;p=p->next)
168     {
169         if(cv_stricmp(p->pName,name)==0) break;
170         pPrev = p;
171     }
172     if(p)
173     {
174         if(pPrev)
175         {
176             pPrev->next = p->next;
177         }
178         else
179         {
180             m_pParamList = p->next;
181         }
182         FreeParam(&p);
183     }
184 }/* DelParam */
185
186
187 const char* CvVSModule::GetParamName(int index)
188 {
189     CvDefParam* p = GetParamPtr(index);
190     return p?p->pName:NULL;
191 }
192 const char* CvVSModule::GetParamComment(const char* name)
193 {
194     CvDefParam* p = GetParamPtr(name);
195     if(p && p->pComment) return p->pComment;
196     return NULL;
197 }
198 double CvVSModule::GetParam(const char* name)
199 {
200     CvDefParam* p = GetParamPtr(name);
201     if(p)
202     {
203         if(p->pDouble) return p->pDouble[0];
204         if(p->pFloat) return p->pFloat[0];
205         if(p->pInt) return p->pInt[0];
206     }
207     return 0;
208 }
209
210 const char* CvVSModule::GetParamStr(const char* name)
211 {
212     CvDefParam* p = GetParamPtr(name);
213     return p?p->Str:NULL;
214 }
215 void   CvVSModule::SetParam(const char* name, double val)
216 {
217     CvDefParam* p = m_pParamList;
218     for(;p;p=p->next)
219     {
220         if(cv_stricmp(p->pName,name) != 0) continue;
221         if(p->pDouble)p->pDouble[0] = val;
222         if(p->pFloat)p->pFloat[0] = (float)val;
223         if(p->pInt)p->pInt[0] = cvRound(val);
224     }
225 }
226 void   CvVSModule::SetParamStr(const char* name, const char* str)
227 {
228     CvDefParam* p = m_pParamList;
229     for(; p; p=p->next)
230     {
231         if(cv_stricmp(p->pName,name) != 0) continue;
232         if(p->pStr)
233         {
234             if(p->Str)free(p->Str);
235             p->Str = NULL;
236             if(str)p->Str = strdup(str);
237             p->pStr[0] = p->Str;
238         }
239     }
240     /* Convert to double and set: */
241     if(str) SetParam(name,atof(str));
242 }
243
244 void CvVSModule::TransferParamsFromChild(CvVSModule* pM, const char* prefix)
245 {
246     char    tmp[1024];
247     const char*   FN = NULL;
248     int i;
249     for(i=0;;++i)
250     {
251         const char* N = pM->GetParamName(i);
252         if(N == NULL) break;
253         FN = N;
254         if(prefix)
255         {
256             strcpy(tmp,prefix);
257             strcat(tmp,"_");
258             FN = strcat(tmp,N);
259         }
260
261         if(!IsParam(FN))
262         {
263             if(pM->GetParamStr(N))
264             {
265                 AddParam(FN,(const char**)NULL);
266             }
267             else
268             {
269                 AddParam(FN);
270             }
271         }
272         if(pM->GetParamStr(N))
273         {
274             const char* val = pM->GetParamStr(N);
275             SetParamStr(FN,val);
276         }
277         else
278         {
279             double val = pM->GetParam(N);
280             SetParam(FN,val);
281         }
282         CommentParam(FN, pM->GetParamComment(N));
283     }/* transfer next param */
284 }/* Transfer params */
285
286 void CvVSModule::TransferParamsToChild(CvVSModule* pM, char* prefix)
287 {
288     char    tmp[1024];
289     int i;
290     for(i=0;;++i)
291     {
292         const char* N = pM->GetParamName(i);
293         if(N == NULL) break;
294         if(prefix)
295         {
296             strcpy(tmp,prefix);
297             strcat(tmp,"_");
298             strcat(tmp,N);
299         }
300         else
301         {
302             strcpy(tmp,N);
303         }
304
305         if(IsParam(tmp))
306         {
307             if(GetParamStr(tmp))
308                 pM->SetParamStr(N,GetParamStr(tmp));
309             else
310                 pM->SetParam(N,GetParam(tmp));
311         }
312     }/* Transfer next parameter */
313     pM->ParamUpdate();
314 }/* Transfer params */
315
316 void CvVSModule::ParamUpdate(){}
317
318 const char*   CvVSModule::GetTypeName()
319 {
320     return m_pModuleTypeName;
321 }
322
323 int     CvVSModule::IsModuleTypeName(const char* name)
324 {
325     return m_pModuleTypeName?(cv_stricmp(m_pModuleTypeName,name)==0):0;
326 }
327
328 char*   CvVSModule::GetModuleName()
329 {
330     return m_pModuleName;
331 }
332
333 int     CvVSModule::IsModuleName(const char* name)
334 {
335     return m_pModuleName?(cv_stricmp(m_pModuleName,name)==0):0;
336 }
337
338 void CvVSModule::SetNickName(const char* pStr)
339 {
340     if(m_pNickName)
341         free(m_pNickName);
342
343     m_pNickName = NULL;
344
345     if(pStr)
346         m_pNickName = strdup(pStr);
347 }
348
349 const char* CvVSModule::GetNickName()
350 {
351     return m_pNickName ? m_pNickName : "unknown";
352 }
353
354 void CvVSModule::SaveState(CvFileStorage*)
355 {
356 }
357
358 void CvVSModule::LoadState(CvFileStorage*, CvFileNode*)
359 {
360 }
361
362 /////////////////////////////////////////////////////////////////////
363
364 void cvWriteStruct(CvFileStorage* fs, const char* name, void* addr, const char* desc, int num)
365 {
366     cvStartWriteStruct(fs,name,CV_NODE_SEQ|CV_NODE_FLOW);
367     cvWriteRawData(fs,addr,num,desc);
368     cvEndWriteStruct(fs);
369 }
370
371 void cvReadStructByName(CvFileStorage* fs, CvFileNode* node, const char* name, void* addr, const char* desc)
372 {
373     CvFileNode* pSeqNode = cvGetFileNodeByName(fs, node, name);
374     if(pSeqNode==NULL)
375     {
376         printf("WARNING!!! Can't read structure %s\n",name);
377     }
378     else
379     {
380         if(CV_NODE_IS_SEQ(pSeqNode->tag))
381         {
382             cvReadRawData( fs, pSeqNode, addr, desc );
383         }
384         else
385         {
386             printf("WARNING!!! Structure %s is not sequence and can not be read\n",name);
387         }
388     }
389 }
390
391 ////////////////////////////// CvFGDetector ///////////////////////////////////////////
392
393 CvFGDetector::CvFGDetector()
394 {
395     SetTypeName("FGDetector");
396 }
397
398 void cvReleaseFGDetector(CvFGDetector** ppT )
399 {
400     ppT[0]->Release();
401     ppT[0] = 0;
402 }
403
404 ///////////////////////////// CvBlobSeq ///////////////////////////////////////////////
405
406 CvBlobTrackSeq::CvBlobTrackSeq(int TrackSize)
407 {
408     m_pMem = cvCreateMemStorage();
409     m_pSeq = cvCreateSeq(0,sizeof(CvSeq),TrackSize,m_pMem);
410 }
411
412 CvBlobTrackSeq::~CvBlobTrackSeq()
413 {
414     Clear();
415     cvReleaseMemStorage(&m_pMem);
416 }
417
418 CvBlobTrack* CvBlobTrackSeq::GetBlobTrack(int TrackIndex)
419 {
420     return (CvBlobTrack*)cvGetSeqElem(m_pSeq,TrackIndex);
421 }
422
423 CvBlobTrack* CvBlobTrackSeq::GetBlobTrackByID(int TrackID)
424 {
425     int i;
426     for(i=0; i<m_pSeq->total; ++i)
427     {
428         CvBlobTrack* pP = GetBlobTrack(i);
429         if(pP && pP->TrackID == TrackID)
430             return pP;
431     }
432     return NULL;
433 }
434
435 void CvBlobTrackSeq::DelBlobTrack(int TrackIndex)
436 {
437     CvBlobTrack* pP = GetBlobTrack(TrackIndex);
438     if(pP && pP->pBlobSeq) delete pP->pBlobSeq;
439     cvSeqRemove(m_pSeq,TrackIndex);
440 }
441
442 void CvBlobTrackSeq::DelBlobTrackByID(int TrackID)
443 {
444     int i;
445     for(i=0; i<m_pSeq->total; ++i)
446     {
447         CvBlobTrack* pP = GetBlobTrack(i);
448         if(TrackID == pP->TrackID)
449         {
450             DelBlobTrack(i);
451             return;
452         }
453     }
454 }
455
456 void CvBlobTrackSeq::Clear()
457 {
458     int i;
459     for(i=GetBlobTrackNum();i>0;i--)
460     {
461         DelBlobTrack(i-1);
462     }
463     cvClearSeq(m_pSeq);
464 }
465
466 void CvBlobTrackSeq::AddBlobTrack(int TrackID, int StartFrame)
467 {
468     CvBlobTrack N;
469     N.TrackID = TrackID;
470     N.StartFrame = StartFrame;
471     N.pBlobSeq = new CvBlobSeq;
472     cvSeqPush(m_pSeq,&N);
473 }
474
475 int CvBlobTrackSeq::GetBlobTrackNum()
476 {
477     return m_pSeq->total;
478 }
479
480 void cvReleaseBlobDetector(CvBlobDetector** ppBD)
481 {
482     ppBD[0]->Release();
483     ppBD[0] = NULL;
484 }
485
486
487 ///////////////////////////////////// CvObjectDetector /////////////////////////////////
488
489 CvObjectDetector::CvObjectDetector( const char* /*detector_file_name*/ )
490 {
491 }
492
493 CvObjectDetector::~CvObjectDetector()
494 {
495 }
496
497 /*
498  * Release the current detector and load new detector from file
499  * (if detector_file_name is not 0)
500  * Return true on success:
501  */
502 bool CvObjectDetector::Load( const char* /*detector_file_name*/ )
503 {
504     return false;
505 }
506
507 /* Return min detector window size: */
508 CvSize CvObjectDetector::GetMinWindowSize() const
509 {
510     return cvSize(0,0);
511 }
512
513 /* Return max border: */
514 int CvObjectDetector::GetMaxBorderSize() const
515 {
516     return 0;
517 }
518
519 /*
520  * Detect the object on the image and push the detected
521  * blobs into <detected_blob_seq> which must be the sequence of <CvDetectedBlob>s
522  */
523 void CvObjectDetector::Detect( const CvArr* /*img*/,
524                                /* out */ CvBlobSeq* /*detected_blob_seq*/ )
525 {
526 }
527
528 //////////////////////////////// CvBlobTracker //////////////////////////////////////
529
530 CvBlobTracker::CvBlobTracker(){SetTypeName("BlobTracker");}
531
532 /* Process one blob (for multi hypothesis tracing): */
533 void CvBlobTracker::ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
534 {
535     CvBlob* pB;
536     int ID = 0;
537     assert(pBlob);
538     //pBlob->ID;
539     pB = GetBlob(BlobIndex);
540     if(pB)
541         pBlob[0] = pB[0];
542     pBlob->ID = ID;
543 }
544
545 /* Get confidence/wieght/probability (0-1) for blob: */
546 double  CvBlobTracker::GetConfidence(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
547 {
548     return 1;
549 }
550
551 double CvBlobTracker::GetConfidenceList(CvBlobSeq* pBlobList, IplImage* pImg, IplImage* pImgFG)
552 {
553     int     b,bN = pBlobList->GetBlobNum();
554     double  W = 1;
555     for(b=0;b<bN;++b)
556     {
557         CvBlob* pB = pBlobList->GetBlob(b);
558         int     BI = GetBlobIndexByID(pB->ID);
559         W *= GetConfidence(BI,pB,pImg,pImgFG);
560     }
561     return W;
562 }
563
564 void CvBlobTracker::UpdateBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
565 {
566 }
567
568 /* Update all blob models: */
569 void CvBlobTracker::Update(IplImage* pImg, IplImage* pImgFG)
570 {
571     int i;
572     for(i=GetBlobNum();i>0;i--)
573     {
574         CvBlob* pB=GetBlob(i-1);
575         UpdateBlob(i-1, pB, pImg, pImgFG);
576     }
577 }
578
579 /* Return pointer to blob by its unique ID: */
580 int     CvBlobTracker::GetBlobIndexByID(int BlobID)
581 {
582     int i;
583     for(i=GetBlobNum();i>0;i--)
584     {
585         CvBlob* pB=GetBlob(i-1);
586         if(CV_BLOB_ID(pB) == BlobID) return i-1;
587     }
588     return -1;
589 }
590
591 /* Return pointer to blob by its unique ID: */
592 CvBlob* CvBlobTracker::GetBlobByID(int BlobID)
593 {
594     return GetBlob(GetBlobIndexByID(BlobID));
595 }
596
597 /* Delete blob by its ID: */
598 void    CvBlobTracker::DelBlobByID(int BlobID)
599 {
600     DelBlob(GetBlobIndexByID(BlobID));
601 }
602
603 /* Set new parameters for specified (by index) blob: */
604 void    CvBlobTracker::SetBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/)
605 {
606 }
607
608 /* Set new parameters for specified (by ID) blob: */
609 void    CvBlobTracker::SetBlobByID(int BlobID, CvBlob* pBlob)
610 {
611     SetBlob(GetBlobIndexByID(BlobID),pBlob);
612 }
613
614 /*  ===============  MULTI HYPOTHESIS INTERFACE ==================  */
615
616 /* Return number of position hyposetis of currently tracked blob: */
617 int     CvBlobTracker::GetBlobHypNum(int /*BlobIdx*/)
618 {
619     return 1;
620 }
621
622 /* Return pointer to specified blob hypothesis by index blob: */
623 CvBlob* CvBlobTracker::GetBlobHyp(int BlobIndex, int /*hypothesis*/)
624 {
625     return GetBlob(BlobIndex);
626 }
627
628 /* Set new parameters for specified (by index) blob hyp
629  * (can be called several times for each hyp ):
630  */
631 void    CvBlobTracker::SetBlobHyp(int /*BlobIndex*/, CvBlob* /*pBlob*/)
632 {
633 }
634
635 void cvReleaseBlobTracker(CvBlobTracker**ppT )
636 {
637     ppT[0]->Release();
638     ppT[0] = 0;
639 }