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
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
46 typedef struct DefBlobFVN
49 CvBlob BlobSeq[BLOB_NUM];
54 class CvBlobTrackFVGenN: public CvBlobTrackFVGen
60 float m_FVMax[MAX_FV_SIZE];
61 float m_FVMin[MAX_FV_SIZE];
62 float m_FVVar[MAX_FV_SIZE];
64 CvBlob m_BlobSeq[BLOB_NUM];
73 cvClearMemStorage(m_pMem);
74 m_pFVSeq = cvCreateSeq(0,sizeof(CvSeq),sizeof(float)*(m_Dim+1), m_pMem);
79 CvBlobTrackFVGenN(int dim = 2 ):m_BlobList(sizeof(DefBlobFVN))
82 assert(dim <= MAX_FV_SIZE);
92 m_pMem = cvCreateMemStorage();
98 if(m_pMem)cvReleaseMemStorage(&m_pMem);
101 void AddBlob(CvBlob* pBlob)
103 float FV[MAX_FV_SIZE+1];
105 DefBlobFVN* pFVBlob = (DefBlobFVN*)m_BlobList.GetBlobByID(CV_BLOB_ID(pBlob));
107 if(!m_ClearFlag) Clear();
112 BlobNew.blob = pBlob[0];
113 BlobNew.LastFrame = m_Frame;
115 BlobNew.FrameNum = 0;
116 m_BlobList.AddBlob((CvBlob*)&BlobNew);
117 pFVBlob = (DefBlobFVN*)m_BlobList.GetBlobByID(CV_BLOB_ID(pBlob));
118 }/* add new record if need */
119 pFVBlob->blob = pBlob[0];
122 for(i=(BLOB_NUM-1);i>0;--i)
124 pFVBlob->BlobSeq[i] = pFVBlob->BlobSeq[i-1];
127 pFVBlob->BlobSeq[0] = pBlob[0];
130 {/* calc FV position */
131 FV[0] = CV_BLOB_X(pBlob);
132 FV[1] = CV_BLOB_Y(pBlob);
136 { /* add new FV if position is enought */
137 *(int*)(FV+m_Dim) = CV_BLOB_ID(pBlob);
138 cvSeqPush( m_pFVSeq, FV );
140 else if(pFVBlob->FrameNum > BLOB_NUM)
141 { /* calc velocity for more complex FV */
144 { /* average velocity */
145 CvBlob* pBlobSeq = pFVBlob->BlobSeq;
147 for(i=1;i<BLOB_NUM;++i)
149 AverVx += CV_BLOB_X(pBlobSeq+i-1)-CV_BLOB_X(pBlobSeq+i);
150 AverVy += CV_BLOB_Y(pBlobSeq+i-1)-CV_BLOB_Y(pBlobSeq+i);
152 AverVx /= BLOB_NUM-1;
153 AverVy /= BLOB_NUM-1;
160 { /* state duration */
161 float T = (CV_BLOB_WX(pBlob)+CV_BLOB_WY(pBlob))*0.01f;
163 if( fabs(AverVx) < T && fabs(AverVy) < T)
167 FV[4] = (float)pFVBlob->state;
168 }/* state duration */
170 *(int*)(FV+m_Dim) = CV_BLOB_ID(pBlob);
171 cvSeqPush( m_pFVSeq, FV );
172 }/* if velocity is calculated */
175 pFVBlob->LastFrame = m_Frame;
177 void Process(IplImage* pImg, IplImage* /*pFG*/)
180 if(!m_ClearFlag) Clear();
181 for(i=m_BlobList.GetBlobNum();i>0;--i)
182 { /* delete unused blob */
183 DefBlobFVN* pFVBlob = (DefBlobFVN*)m_BlobList.GetBlob(i-1);
184 if(pFVBlob->LastFrame < m_Frame)
186 m_BlobList.DelBlob(i-1);
188 }/* check next blob in list */
192 m_FVMax[0] = (float)(pImg->width-1);
193 m_FVMax[1] = (float)(pImg->height-1);
194 m_FVVar[0] = m_FVMax[0]*0.01f;
195 m_FVVar[1] = m_FVMax[1]*0.01f;
196 m_FVVar[2] = (float)(pImg->width-1)/1440.0f;
197 m_FVMax[2] = (float)(pImg->width-1)*0.02f;
198 m_FVMin[2] = -m_FVMax[2];
199 m_FVVar[3] = (float)(pImg->width-1)/1440.0f;
200 m_FVMax[3] = (float)(pImg->height-1)*0.02f;
201 m_FVMin[3] = -m_FVMax[3];
202 m_FVMax[4] = 25*32.0f; /* max state is 32 sec */
209 virtual void Release(){delete this;};
210 virtual int GetFVSize(){return m_Dim;};
211 virtual int GetFVNum()
213 return m_pFVSeq->total;
215 virtual float* GetFV(int index, int* pFVID)
217 float* pFV = (float*)cvGetSeqElem( m_pFVSeq, index );
218 if(pFVID)pFVID[0] = *(int*)(pFV+m_Dim);
221 virtual float* GetFVMin(){return m_FVMin;}; /* returned pointer to array of minimal values of FV, if return 0 then FVrange is not exist */
222 virtual float* GetFVMax(){return m_FVMax;}; /* returned pointer to array of maximal values of FV, if return 0 then FVrange is not exist */
223 virtual float* GetFVVar(){return m_FVVar;}; /* returned pointer to array of maximal values of FV, if return 0 then FVrange is not exist */
224 };/* CvBlobTrackFVGenN */
226 CvBlobTrackFVGen* cvCreateFVGenP(){return (CvBlobTrackFVGen*)new CvBlobTrackFVGenN(2);}
227 CvBlobTrackFVGen* cvCreateFVGenPV(){return (CvBlobTrackFVGen*)new CvBlobTrackFVGenN(4);}
228 CvBlobTrackFVGen* cvCreateFVGenPVS(){return (CvBlobTrackFVGen*)new CvBlobTrackFVGenN(5);}
231 #define MAX_FV_SIZE 4
232 class CvBlobTrackFVGenSS: public CvBlobTrackFVGen
235 CvBlobSeq m_BlobList;
236 CvMemStorage* m_pMem;
238 float m_FVMax[MAX_FV_SIZE];
239 float m_FVMin[MAX_FV_SIZE];
240 float m_FVVar[MAX_FV_SIZE];
242 CvBlob m_BlobSeq[BLOB_NUM];
249 cvClearMemStorage(m_pMem);
250 m_pFVSeq = cvCreateSeq(0,sizeof(CvSeq),sizeof(float)*(m_Dim+1), m_pMem);
254 CvBlobTrackFVGenSS(int dim = 2 ):m_BlobList(sizeof(DefBlobFVN))
257 assert(dim <= MAX_FV_SIZE);
267 m_pMem = cvCreateMemStorage();
270 ~CvBlobTrackFVGenSS()
272 if(m_pMem)cvReleaseMemStorage(&m_pMem);
275 void AddBlob(CvBlob* pBlob)
277 //float FV[MAX_FV_SIZE+1];
279 DefBlobFVN* pFVBlob = (DefBlobFVN*)m_BlobList.GetBlobByID(CV_BLOB_ID(pBlob));
281 if(!m_ClearFlag) Clear();
286 BlobNew.blob = pBlob[0];
287 BlobNew.LastFrame = m_Frame;
289 BlobNew.FrameNum = 0;
290 m_BlobList.AddBlob((CvBlob*)&BlobNew);
291 pFVBlob = (DefBlobFVN*)m_BlobList.GetBlobByID(CV_BLOB_ID(pBlob));
292 }/* add new record if need */
295 for(i=(BLOB_NUM-1);i>0;--i)
297 pFVBlob->BlobSeq[i] = pFVBlob->BlobSeq[i-1];
300 pFVBlob->BlobSeq[0] = pBlob[0];
302 if(pFVBlob->FrameNum > BLOB_NUM)
303 {/* average velocity */
304 CvBlob* pBlobSeq = pFVBlob->BlobSeq;
305 float T = (CV_BLOB_WX(pBlob)+CV_BLOB_WY(pBlob))*0.01f;
309 for(i=1;i<BLOB_NUM;++i)
311 AverVx += CV_BLOB_X(pBlobSeq+i-1)-CV_BLOB_X(pBlobSeq+i);
312 AverVy += CV_BLOB_Y(pBlobSeq+i-1)-CV_BLOB_Y(pBlobSeq+i);
314 AverVx /= BLOB_NUM-1;
315 AverVy /= BLOB_NUM-1;
317 if( fabs(AverVx) < T && fabs(AverVy) < T)
323 if(pFVBlob->state == 5)
324 { /* object is stoped */
325 float FV[MAX_FV_SIZE];
326 FV[0] = pFVBlob->blob.x;
327 FV[1] = pFVBlob->blob.y;
328 FV[2] = pFVBlob->BlobSeq[0].x;
329 FV[3] = pFVBlob->BlobSeq[0].y;
330 *(int*)(FV+m_Dim) = CV_BLOB_ID(pBlob);
331 cvSeqPush( m_pFVSeq, FV );
332 } /* object is stoped */
335 pFVBlob->LastFrame = m_Frame;
337 void Process(IplImage* pImg, IplImage* /*pFG*/)
341 if(!m_ClearFlag) Clear();
343 for(i=m_BlobList.GetBlobNum();i>0;--i)
344 { /* delete unused blob */
345 DefBlobFVN* pFVBlob = (DefBlobFVN*)m_BlobList.GetBlob(i-1);
346 if(pFVBlob->LastFrame < m_Frame)
348 float FV[MAX_FV_SIZE+1];
349 FV[0] = pFVBlob->blob.x;
350 FV[1] = pFVBlob->blob.y;
351 FV[2] = pFVBlob->BlobSeq[0].x;
352 FV[3] = pFVBlob->BlobSeq[0].y;
353 *(int*)(FV+m_Dim) = CV_BLOB_ID(pFVBlob);
354 cvSeqPush( m_pFVSeq, FV );
355 m_BlobList.DelBlob(i-1);
357 }/* check next blob in list */
359 /* set max min range */
364 m_FVMax[0] = (float)(pImg->width-1);
365 m_FVMax[1] = (float)(pImg->height-1);
366 m_FVMax[2] = (float)(pImg->width-1);
367 m_FVMax[3] = (float)(pImg->height-1);
368 m_FVVar[0] = m_FVMax[0]*0.01f;
369 m_FVVar[1] = m_FVMax[1]*0.01f;
370 m_FVVar[2] = m_FVMax[2]*0.01f;
371 m_FVVar[3] = m_FVMax[3]*0.01f;
376 virtual void Release(){delete this;};
377 virtual int GetFVSize(){return m_Dim;};
378 virtual int GetFVNum()
380 return m_pFVSeq->total;
382 virtual float* GetFV(int index, int* pFVID)
384 float* pFV = (float*)cvGetSeqElem( m_pFVSeq, index );
385 if(pFVID)pFVID[0] = *(int*)(pFV+m_Dim);
388 virtual float* GetFVMin(){return m_FVMin;}; /* returned pointer to array of minimal values of FV, if return 0 then FVrange is not exist */
389 virtual float* GetFVMax(){return m_FVMax;}; /* returned pointer to array of maximal values of FV, if return 0 then FVrange is not exist */
390 virtual float* GetFVVar(){return m_FVVar;}; /* returned pointer to array of maximal values of FV, if return 0 then FVrange is not exist */
391 };/* CvBlobTrackFVGenSS */
392 CvBlobTrackFVGen* cvCreateFVGenSS(){return (CvBlobTrackFVGen*)new CvBlobTrackFVGenSS;}
394 /*======================= TRAJECTORY ANALAZER MODULES =====================*/
395 /* Trajectory Analyser module */
402 CvSparseMatIterator m_SparseIterator;
403 CvSparseNode* m_pSparseNode;
408 CvSparseMat* m_pSparse;
412 DefMat(int dim = 0, int* sizes = NULL, int type = SPARSE)
414 /* create sparse or ND matrix but not both */
415 m_pSparseNode = NULL;
422 if(dim>0 && sizes != 0)
423 Realloc(dim, sizes, type);
427 if(m_pSparse)cvReleaseSparseMat(&m_pSparse);
428 if(m_pND)cvReleaseMatND(&m_pND);
429 if(m_IDXs) cvFree(&m_IDXs);
432 void Realloc(int dim, int* sizes, int type = SPARSE)
434 if(m_pSparse)cvReleaseSparseMat(&m_pSparse);
435 if(m_pND)cvReleaseMatND(&m_pND);
441 for(size=1,i=0;i<dim;++i)
454 }/* define matrix type */
458 m_pSparse = cvCreateSparseMat( dim, sizes, CV_32SC1 );
463 m_pND = cvCreateMatND( dim, sizes, CV_32SC1 );
465 m_IDXs = (int*)cvAlloc(sizeof(int)*dim);
471 void Save(char* File)
473 if(m_pSparse)cvSave(File, m_pSparse );
474 if(m_pND)cvSave(File, m_pND );
476 void Save(CvFileStorage* fs, char* name)
480 cvWrite(fs, name, m_pSparse );
484 cvWrite(fs, name, m_pND );
487 void Load(char* File)
489 CvFileStorage* fs = cvOpenFileStorage( File, NULL, CV_STORAGE_READ );
493 if(m_pSparse) cvReleaseSparseMat(&m_pSparse);
494 if(m_pND) cvReleaseMatND(&m_pND);
498 if(ptr && CV_IS_MATND_HDR(ptr)) m_pND = (CvMatND*)ptr;
499 if(ptr && CV_IS_SPARSE_MAT_HDR(ptr)) m_pSparse = (CvSparseMat*)ptr;
500 cvReleaseFileStorage(&fs);
505 void Load(CvFileStorage* fs, CvFileNode* node, char* name)
507 CvFileNode* n = cvGetFileNodeByName(fs,node,name);
508 void* ptr = n?cvRead(fs,n):NULL;
511 if(m_pSparse) cvReleaseSparseMat(&m_pSparse);
512 if(m_pND) cvReleaseMatND(&m_pND);
515 if(CV_IS_MATND_HDR(ptr)) m_pND = (CvMatND*)ptr;
516 if(CV_IS_SPARSE_MAT_HDR(ptr)) m_pSparse = (CvSparseMat*)ptr;
520 printf("WARNING!!! Can't load %s matrix\n",name);
529 {/* calculate Volume of loaded hist */
530 CvSparseMatIterator mat_iterator;
531 CvSparseNode* node = cvInitSparseMatIterator( m_pSparse, &mat_iterator );
533 for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))
535 int val = *(int*)CV_NODE_VAL( m_pSparse, node ); /* get value of the element
536 (assume that the type is CV_32SC1) */
538 if(m_Max < val)m_Max = val;
540 }/* calculate Volume of loaded hist */
542 {/* calculate Volume of loaded hist */
546 cvGetMat( m_pND, &mat, NULL, 1 );
548 vol = cvSum(&mat).val[0];
549 m_Volume = cvRound(vol);
550 cvMinMaxLoc( &mat, NULL, &max_val);
551 m_Max = cvRound(max_val);
552 /* MUST BE WRITTEN LATER */
553 }/* calculate Volume of loaded hist */
555 int* GetPtr(int* indx)
557 if(m_pSparse) return (int*)cvPtrND( m_pSparse, indx, NULL, 1, NULL);
558 if(m_pND) return (int*)cvPtrND( m_pND, indx, NULL, 1, NULL);
561 int GetVal(int* indx)
563 int* p = GetPtr(indx);
567 int Add(int* indx, int val)
570 int* pVal = GetPtr(indx);
571 if(pVal == NULL) return -1;
575 if(m_Max < NewVal)m_Max = NewVal;
578 void Add(DefMat* pMatAdd)
582 for(Val = pMatAdd->GetNext(&pIDXS, 1 );pIDXS;Val=pMatAdd->GetNext(&pIDXS, 0 ))
587 int SetMax(int* indx, int val)
590 int* pVal = GetPtr(indx);
591 if(pVal == NULL) return -1;
594 m_Volume += val-pVal[0];
598 if(m_Max < NewVal)m_Max = NewVal;
601 int GetNext(int** pIDXS, int init = 0)
607 m_pSparseNode = (init || m_pSparseNode==NULL)?
608 cvInitSparseMatIterator( m_pSparse, &m_SparseIterator ):
609 cvGetNextSparseNode( &m_SparseIterator );
613 int* pVal = (int*)CV_NODE_VAL( m_pSparse, m_pSparseNode );
614 if(pVal)Val = pVal[0];
615 pIDXS[0] = CV_NODE_IDX( m_pSparse, m_pSparseNode );
625 m_IDXs[i] = cvGetDimSize( m_pND, i )-1;
628 Val = GetVal(m_IDXs);
636 m_IDXs[i] = cvGetDimSize( m_pND, i )-1;
645 Val = GetVal(m_IDXs);
655 typedef struct DefTrackFG
658 // CvBlobTrackFVGen* pFVGen;
663 class CvBlobTrackAnalysisHist : public CvBlobTrackAnalysis
665 /*---------------- internal functions --------------------*/
669 char* m_SmoothKernel;
670 float m_AbnormalThreshold;
674 char m_DataFileName[1024];
678 int m_HistVolumeSaved;
682 CvBlobSeq m_TrackFGList;
683 //CvBlobTrackFVGen* (*m_CreateFVGen)();
684 CvBlobTrackFVGen* m_pFVGen;
687 if(m_DataFileName[0])
689 m_HistMat.Save(m_DataFileName);
690 m_HistVolumeSaved = m_HistMat.m_Volume;
695 if(m_DataFileName[0])m_HistMat.Load(m_DataFileName);
696 m_HistVolumeSaved = m_HistMat.m_Volume;
700 m_pFVi = (int*)cvAlloc(sizeof(int)*m_Dim);
701 m_pFViVar = (int*)cvAlloc(sizeof(int)*m_Dim);
702 m_pFViVarRes = (int*)cvAlloc(sizeof(int)*m_Dim);
703 m_Sizes = (int*)cvAlloc(sizeof(int)*m_Dim);
705 { /* create init sparce matrix */
707 for(i=0;i<m_Dim;++i)m_Sizes[i] = m_BinNum;
708 m_HistMat.Realloc(m_Dim,m_Sizes,SPARSE);
709 m_HistVolumeSaved = 0;
710 } /* create init sparce matrix */
715 for(i=m_TrackFGList.GetBlobNum();i>0;--i)
717 //DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlob(i-1);
718 // pF->pFVGen->Release();
719 m_TrackFGList.DelBlob(i-1);
723 cvFree(&m_pFViVarRes);
726 virtual void ParamUpdate()
728 if(m_BinNum != m_BinNumParam)
731 m_BinNum = m_BinNumParam;
736 CvBlobTrackAnalysisHist(CvBlobTrackFVGen* (*createFVGen)()):m_TrackFGList(sizeof(DefTrackFG))
738 m_pFVGen = createFVGen();
739 m_Dim = m_pFVGen->GetFVSize();
744 m_DataFileName[0] = 0;
746 m_AbnormalThreshold = 0.02f;
747 AddParam("AbnormalThreshold",&m_AbnormalThreshold);
748 CommentParam("AbnormalThreshold","If trajectory histogram value is lesst then <AbnormalThreshold*DataBaseTrackNum> then trajectory is abnormal");
751 AddParam("SmoothRadius",&m_SmoothRadius);
752 CommentParam("AbnormalThreshold","Radius (in bins) for histogramm smothing");
754 m_SmoothKernel = "L";
755 AddParam("SmoothKernel",&m_SmoothKernel);
756 CommentParam("SmoothKernel","L - Linear, G - Gaussian");
759 m_BinNumParam = m_BinNum;
760 AddParam("BinNum",&m_BinNumParam);
761 CommentParam("BinNum","Number of bin for each dimention of feature vector");
765 ~CvBlobTrackAnalysisHist()
772 /*----------------- interface --------------------*/
773 virtual void AddBlob(CvBlob* pBlob)
775 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlobByID(CV_BLOB_ID(pBlob));
777 { /* create new filter */
781 F.LastFrame = m_Frame;
782 // F.pFVGen = m_CreateFVGen();
783 F.pHist = new DefMat(m_Dim,m_Sizes,SPARSE);
784 m_TrackFGList.AddBlob((CvBlob*)&F);
785 pF = (DefTrackFG*)m_TrackFGList.GetBlobByID(CV_BLOB_ID(pBlob));
790 pF->LastFrame = m_Frame;
791 m_pFVGen->AddBlob(pBlob);
793 virtual void Process(IplImage* pImg, IplImage* pFG)
796 m_pFVGen->Process(pImg, pFG);
797 int SK = m_SmoothKernel[0];
799 for(i=0;i<m_pFVGen->GetFVNum();++i)
802 float* pFV = m_pFVGen->GetFV(i,&BlobID);
803 float* pFVMax = m_pFVGen->GetFVMax();
804 float* pFVMin = m_pFVGen->GetFVMin();
805 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlobByID(BlobID);
810 pF->LastFrame = m_Frame;
817 float f0 = pFVMin?pFVMin[j]:0;
818 float f1 = pFVMax?pFVMax[j]:1;
820 index = cvRound((m_BinNum-1)*(pFV[j]-f0)/(f1-f0));
822 if(index>=m_BinNum)index=m_BinNum-1;
827 HistVal = m_HistMat.GetVal(m_pFVi);/* get bin value*/
830 float T = m_HistMat.m_Max*m_AbnormalThreshold; /* calc threshold */
832 if(m_TrackNum>0) T = 256.0f * m_TrackNum*m_AbnormalThreshold;
835 pF->state = (T - HistVal)/(T*0.2f) + 0.5f;
837 if(pF->state<0)pF->state=0;
838 if(pF->state>1)pF->state=1;
841 {/* if new FV then add it to trajectory histogramm */
843 int r = m_SmoothRadius;
845 // printf("BLob %3d NEW FV [", CV_BLOB_ID(pF));
846 // for(i=0;i<m_Dim;++i) printf("%d,", m_pFVi[i]);
861 m_pFViVarRes[i] = m_pFVi[i]+m_pFViVar[i];
862 if(m_pFViVarRes[i]<0) good= 0;
863 if(m_pFViVarRes[i]>=m_BinNum) good= 0;
864 dist += m_pFViVar[i]*m_pFViVar[i];
865 }/* calc next dimention */
867 if(SK=='G' || SK=='g')
869 double dist2 = dist/(r*r);
870 HistAdd = cvRound(256*exp(-dist2)); /* Hist Add for (dist=1) = 25.6*/
872 else if(SK=='L' || SK=='l')
874 dist = (float)(sqrt(dist)/(r+1));
875 HistAdd = cvRound(256*(1-dist));
879 HistAdd = 255; /* flat smothing */
882 if(good && HistAdd>0)
885 pF->pHist->SetMax(m_pFViVarRes, HistAdd);
890 if((m_pFViVar[i]++) < r)
893 }/* increase next dim var*/
895 }/* next variation */
899 {/* check all blob from list */
901 for(i=m_TrackFGList.GetBlobNum();i>0;--i)
902 {/* add histogramm and delete blob from list */
903 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlob(i-1);
904 if(pF->LastFrame+3 < m_Frame && pF->pHist)
906 m_HistMat.Add(pF->pHist);
909 m_TrackFGList.DelBlob(i-1);
920 IplImage* pI = cvCloneImage(pImg);
923 for(Val = m_HistMat.GetNext(&idxs,1);idxs;Val=m_HistMat.GetNext(&idxs,0))
924 {/* draw all elements */
929 if(Val == 0) continue;
931 vf = (float)Val/(m_HistMat.m_Max?m_HistMat.m_Max:1);
932 x = cvRound((float)(pI->width-1)*(float)idxs[0] / (float)m_BinNum);
933 y = cvRound((float)(pI->height-1)*(float)idxs[1] / (float)m_BinNum);
935 cvCircle(pI, cvPoint(x,y), cvRound(vf*pI->height/(m_BinNum*2)),CV_RGB(255,0,0),CV_FILLED);
938 int dx = -2*(idxs[2]-m_BinNum/2);
939 int dy = -2*(idxs[3]-m_BinNum/2);
940 cvLine(pI,cvPoint(x,y),cvPoint(x+dx,y+dy),CV_RGB(0,cvRound(vf*255),1));
943 m_pFVGen->GetFVMax()[0]==m_pFVGen->GetFVMax()[2] &&
944 m_pFVGen->GetFVMax()[1]==m_pFVGen->GetFVMax()[3])
946 int x = cvRound((float)(pI->width-1)*(float)idxs[2] / (float)m_BinNum);
947 int y = cvRound((float)(pI->height-1)*(float)idxs[3] / (float)m_BinNum);
948 cvCircle(pI, cvPoint(x,y), cvRound(vf*pI->height/(m_BinNum*2)),CV_RGB(0,0,255),CV_FILLED);
950 }/* draw all elements */
952 for(i=m_TrackFGList.GetBlobNum();i>0;--i)
954 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlob(i-1);
955 DefMat* pHist = pF?pF->pHist:NULL;
957 if(pHist==NULL) continue;
959 for(Val = pHist->GetNext(&idxs,1);idxs;Val=pHist->GetNext(&idxs,0))
960 {/* draw all elements */
965 if(Val == 0) continue;
967 vf = (float)Val/(pHist->m_Max?pHist->m_Max:1);
968 x = cvRound((float)(pI->width-1)*(float)idxs[0] / (float)m_BinNum);
969 y = cvRound((float)(pI->height-1)*(float)idxs[1] / (float)m_BinNum);
971 cvCircle(pI, cvPoint(x,y), cvRound(2*vf),CV_RGB(0,0,cvRound(255*vf)),CV_FILLED);
974 int dx = -2*(idxs[2]-m_BinNum/2);
975 int dy = -2*(idxs[3]-m_BinNum/2);
976 cvLine(pI,cvPoint(x,y),cvPoint(x+dx,y+dy),CV_RGB(0,0,255));
979 m_pFVGen->GetFVMax()[0]==m_pFVGen->GetFVMax()[2] &&
980 m_pFVGen->GetFVMax()[1]==m_pFVGen->GetFVMax()[3])
981 { /* if SS feature vector */
982 int x = cvRound((float)(pI->width-1)*(float)idxs[2] / (float)m_BinNum);
983 int y = cvRound((float)(pI->height-1)*(float)idxs[3] / (float)m_BinNum);
984 cvCircle(pI, cvPoint(x,y), cvRound(vf*pI->height/(m_BinNum*2)),CV_RGB(0,0,255),CV_FILLED);
986 }/* draw all elements */
989 //cvNamedWindow("Hist",0);
990 //cvShowImage("Hist", pI);
994 float GetState(int BlobID)
996 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlobByID(BlobID);
997 return pF?pF->state:0.0f;
999 /* return 0 if trajectory is normal
1000 return >0 if trajectory abnormal */
1001 virtual char* GetStateDesc(int BlobID)
1003 if(GetState(BlobID)>0.5) return "abnormal";
1006 virtual void SetFileName(char* DataBaseName)
1008 if(m_HistMat.m_Volume!=m_HistVolumeSaved)SaveHist();
1009 m_DataFileName[0] = 0;
1012 strncpy(m_DataFileName,DataBaseName,1000);
1013 strcat(m_DataFileName, ".yml");
1017 virtual void SaveState(CvFileStorage* fs)
1019 int b, bN = m_TrackFGList.GetBlobNum();
1020 cvWriteInt(fs,"BlobNum",bN);
1021 cvStartWriteStruct(fs,"BlobList",CV_NODE_SEQ);
1024 DefTrackFG* pF = (DefTrackFG*)m_TrackFGList.GetBlob(b);
1025 cvStartWriteStruct(fs,NULL,CV_NODE_MAP);
1026 cvWriteStruct(fs,"Blob", &(pF->blob), "ffffi");
1027 cvWriteInt(fs,"LastFrame",pF->LastFrame);
1028 cvWriteReal(fs,"State",pF->state);
1029 pF->pHist->Save(fs, "Hist");
1030 cvEndWriteStruct(fs);
1032 cvEndWriteStruct(fs);
1033 m_HistMat.Save(fs, "Hist");
1035 virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
1037 CvFileNode* pBLN = cvGetFileNodeByName(fs,node,"BlobList");
1039 if(pBLN && CV_NODE_IS_SEQ(pBLN->tag))
1041 int b, bN = pBLN->data.seq->total;
1044 DefTrackFG* pF = NULL;
1046 CvFileNode* pBN = (CvFileNode*)cvGetSeqElem(pBLN->data.seq,b);
1049 cvReadStructByName(fs, pBN, "Blob", &Blob, "ffffi");
1051 pF = (DefTrackFG*)m_TrackFGList.GetBlobByID(Blob.ID);
1052 if(pF==NULL) continue;
1054 pF->state = (float)cvReadIntByName(fs,pBN,"State",cvRound(pF->state));
1056 pF->pHist->Load(fs,pBN,"Hist");
1060 m_HistMat.Load(fs, node, "Hist");
1064 virtual void Release(){ delete this; };
1070 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistP()
1071 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisHist(cvCreateFVGenP);}
1072 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPV()
1073 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisHist(cvCreateFVGenPV);}
1074 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPVS()
1075 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisHist(cvCreateFVGenPVS);}
1076 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistSS()
1077 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisHist(cvCreateFVGenSS);}
1079 typedef struct DefTrackSVM
1082 // CvBlobTrackFVGen* pFVGen;
1090 class CvBlobTrackAnalysisSVM : public CvBlobTrackAnalysis
1092 /*---------------- internal functions --------------------*/
1094 CvMemStorage* m_pMem;
1097 char m_DataFileName[1024];
1100 //CvStatModel* m_pStatModel;
1103 CvMat* m_pTrainData;
1104 int m_LastTrainDataSize;
1105 // CvBlobTrackFVGen* (*m_CreateFVGen)();
1106 CvBlobTrackFVGen* m_pFVGen;
1109 IplImage* m_pStatImg; /* for debug purpose */
1111 void RetrainStatModel()
1113 ///////// !!!!! TODO !!!!! Repair /////////////
1116 CvSVMModelParams SVMParams = {0};
1117 CvStatModel* pM = NULL;
1120 memset(&SVMParams,0,sizeof(SVMParams));
1121 SVMParams.svm_type = CV_SVM_ONE_CLASS;
1122 SVMParams.kernel_type = CV_SVM_RBF;
1123 SVMParams.gamma = 2.0/(m_RBFWidth*m_RBFWidth);
1124 SVMParams.nu = m_NU;
1125 SVMParams.degree = 3;
1126 SVMParams.criteria = cvTermCriteria(CV_TERMCRIT_EPS, 100, 1e-3 );
1131 if(m_pTrainData == NULL) return;
1133 int64 TickCount = cvGetTickCount();
1134 printf("Frame: %d\n Retrain SVM\nData Size = %d\n",m_Frame, m_pTrainData->rows);
1135 pM = cvTrainSVM( m_pTrainData,CV_ROW_SAMPLE, NULL, (CvStatModelParams*)&SVMParams, NULL, NULL);
1136 TickCount = cvGetTickCount() - TickCount ;
1137 printf("SV Count = %d\n",((CvSVMModel*)pM)->sv_total);
1138 printf("Processing Time = %.1f(ms)\n",TickCount/(1000*cvGetTickFrequency()));
1141 if(pM==NULL) return;
1142 if(m_pStatModel) cvReleaseStatModel(&m_pStatModel);
1145 if(m_pTrainData && m_Wnd)
1148 IplImage* pW = cvCreateImage(m_ImgSize,IPL_DEPTH_32F,1);
1149 IplImage* pI = cvCreateImage(m_ImgSize,IPL_DEPTH_8U,1);
1150 float* pFVVar = m_pFVGen->GetFVVar();
1153 for(i=0;i<m_pTrainData->rows;++i)
1154 {/* draw all elements */
1155 float* pFV = (float*)(m_pTrainData->data.ptr + m_pTrainData->step*i);
1156 int x = cvRound(pFV[0]*pFVVar[0]);
1157 int y = cvRound(pFV[1]*pFVVar[1]);
1161 if(x>=pW->width)x=pW->width-1;
1163 if(y>=pW->height)y=pW->height-1;
1165 r = ((float*)(pW->imageData + y*pW->widthStep))[x];
1167 ((float*)(pW->imageData + y*pW->widthStep))[x] = r;
1169 if(r>MaxVal)MaxVal=r;
1171 if(MaxVal>0)cvConvertScale(pW,pI,255/MaxVal,0);
1172 cvNamedWindow("SVMData",0);
1173 cvShowImage("SVMData",pI);
1174 cvSaveImage("SVMData.bmp",pI);
1175 cvReleaseImage(&pW);
1176 cvReleaseImage(&pI);
1177 }/* prepare for debug */
1179 if(m_pStatModel && m_Wnd && m_Dim == 2)
1181 float* pFVVar = m_pFVGen->GetFVVar();
1183 if(m_pStatImg==NULL)
1185 m_pStatImg = cvCreateImage(m_ImgSize,IPL_DEPTH_8U,1);
1188 for(y=0;y<m_pStatImg->height;y+=1)for(x=0;x<m_pStatImg->width;x+=1)
1189 {/* draw all elements */
1191 uchar* pData = (uchar*)m_pStatImg->imageData + x + y*m_pStatImg->widthStep;
1193 float xy[2] = {x/pFVVar[0],y/pFVVar[1]};
1194 cvInitMatHeader( &FVmat, 1, 2, CV_32F, xy );
1195 res = cvStatModelPredict( m_pStatModel, &FVmat, NULL );
1196 pData[0]=((res>0.5)?255:0);
1198 cvNamedWindow("SVMMask",0);
1199 cvShowImage("SVMMask",m_pStatImg);
1200 cvSaveImage("SVMMask.bmp",m_pStatImg);
1201 }/* prepare for debug */
1204 void SaveStatModel()
1206 if(m_DataFileName[0])
1208 if(m_pTrainData)cvSave(m_DataFileName, m_pTrainData);
1211 void LoadStatModel()
1213 if(m_DataFileName[0])
1215 CvMat* pTrainData = (CvMat*)cvLoad(m_DataFileName);
1216 if(CV_IS_MAT(pTrainData) && pTrainData->width == m_Dim)
1218 if(m_pTrainData) cvReleaseMat(&m_pTrainData);
1219 m_pTrainData = pTrainData;
1225 CvBlobTrackAnalysisSVM(CvBlobTrackFVGen* (*createFVGen)()):m_Tracks(sizeof(DefTrackSVM))
1227 m_pFVGen = createFVGen();
1228 m_Dim = m_pFVGen->GetFVSize();
1229 m_pFV = (float*)cvAlloc(sizeof(float)*m_Dim);
1232 m_pTrainData = NULL;
1233 m_pStatModel = NULL;
1234 m_DataFileName[0] = 0;
1236 m_LastTrainDataSize = 0;
1239 AddParam("Nu",&m_NU);
1240 CommentParam("Nu","Parameters that tunes SVM border elastic");
1243 AddParam("RBFWidth",&m_RBFWidth);
1244 CommentParam("RBFWidth","Parameters that tunes RBF kernel function width.");
1247 ~CvBlobTrackAnalysisSVM()
1251 for(i=m_Tracks.GetBlobNum();i>0;--i)
1253 DefTrackSVM* pF = (DefTrackSVM*)m_Tracks.GetBlob(i-1);
1254 if(pF->pMem) cvReleaseMemStorage(&pF->pMem);
1255 //pF->pFVGen->Release();
1257 if(m_pStatImg)cvReleaseImage(&m_pStatImg);
1261 /*----------------- interface --------------------*/
1262 virtual void AddBlob(CvBlob* pBlob)
1264 DefTrackSVM* pF = (DefTrackSVM*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
1266 m_pFVGen->AddBlob(pBlob);
1269 { /* create new record */
1273 F.LastFrame = m_Frame;
1274 //F.pFVGen = m_CreateFVGen();
1275 F.pMem = cvCreateMemStorage();
1276 F.pFVSeq = cvCreateSeq(0,sizeof(CvSeq),sizeof(float)*m_Dim,F.pMem);
1282 m_Tracks.AddBlob((CvBlob*)&F);
1283 pF = (DefTrackSVM*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
1287 pF->blob = pBlob[0];
1288 pF->LastFrame = m_Frame;
1290 virtual void Process(IplImage* pImg, IplImage* pFG)
1293 float* pFVVar = m_pFVGen->GetFVVar();
1295 m_pFVGen->Process(pImg, pFG);
1296 m_ImgSize = cvSize(pImg->width,pImg->height);
1298 for(i=m_pFVGen->GetFVNum();i>0;--i)
1301 float* pFV = m_pFVGen->GetFV(i,&BlobID);
1302 DefTrackSVM* pF = (DefTrackSVM*)m_Tracks.GetBlobByID(BlobID);
1313 for(j=0;j<m_Dim;++j)
1315 m_pFV[j] = pFV[j]/pFVVar[j];
1317 cvInitMatHeader( &FVmat, 1, m_Dim, CV_32F, m_pFV );
1318 //pF->state = cvStatModelPredict( m_pStatModel, &FVmat, NULL )<0.5;
1322 dx = (pF->blob.x - pF->BlobLast.x);
1323 dy = (pF->blob.y - pF->BlobLast.y);
1325 if(pF->BlobLast.x<0 || (dx*dx+dy*dy) >= 2*2)
1326 { /* add feature vector to train data base */
1327 pF->BlobLast = pF->blob;
1328 cvSeqPush(pF->pFVSeq,pFV);
1330 }/* process one blob */
1333 for(i=m_Tracks.GetBlobNum();i>0;--i)
1334 {/* check each blob record */
1335 DefTrackSVM* pF = (DefTrackSVM*)m_Tracks.GetBlob(i-1);
1336 if(pF->LastFrame+3 < m_Frame )
1337 {/* retrain stat model and delete blob filter */
1339 int old_height = m_pTrainData?m_pTrainData->height:0;
1340 int height = old_height + pF->pFVSeq->total*mult;
1341 CvMat* pTrainData = cvCreateMat(height, m_Dim, CV_32F);
1343 if(m_pTrainData && pTrainData)
1344 { /* create new train data matrix */
1345 int h = pTrainData->height;
1346 pTrainData->height = MIN(pTrainData->height, m_pTrainData->height);
1347 cvCopy(m_pTrainData,pTrainData);
1348 pTrainData->height = h;
1350 for(j=0;j<pF->pFVSeq->total;++j)
1351 {/* copy new data to train data */
1352 float* pFVVar = m_pFVGen->GetFVVar();
1353 float* pFV = (float*)cvGetSeqElem(pF->pFVSeq,j);
1358 float* pTD = (float*)CV_MAT_ELEM_PTR( pTrainData[0], old_height+j*mult+k, 0);
1359 memcpy(pTD,pFV,sizeof(float)*m_Dim);
1361 if(pFVVar)for(t=0;t<m_Dim;++t)
1363 pTD[t] /= pFVVar[t];
1368 for(t=0;t<m_Dim;++t)
1370 pTD[t] += m_RBFWidth*0.5f*(1-2.0f*rand()/(float)RAND_MAX);
1374 }/* next new data */
1376 if(m_pTrainData) cvReleaseMat(&m_pTrainData);
1377 m_pTrainData = pTrainData;
1379 /* delete track record */
1380 cvReleaseMemStorage(&pF->pMem);
1382 m_Tracks.DelBlob(i-1);
1386 /* retraind data each 1 minute if new data exist */
1387 if(m_Frame%(25*60) == 0 && m_pTrainData && m_pTrainData->rows > m_LastTrainDataSize)
1394 if(m_Wnd && m_Dim==2)
1397 IplImage* pI = cvCloneImage(pImg);
1399 if(m_pStatModel && m_pStatImg)
1400 for(y=0;y<pI->height;y+=2)
1402 uchar* pStatData = (uchar*)m_pStatImg->imageData + y*m_pStatImg->widthStep;
1403 uchar* pData = (uchar*)pI->imageData + y*pI->widthStep;
1404 for(x=0;x<pI->width;x+=2)
1405 {/* draw all elements */
1406 int d = pStatData[x];
1407 d = (d<<8) | (d^0xff);
1408 *(ushort*)(pData + x*3) = (ushort)d;
1412 //cvNamedWindow("SVMMap",0);
1413 //cvShowImage("SVMMap", pI);
1414 cvReleaseImage(&pI);
1417 float GetState(int BlobID)
1419 DefTrackSVM* pF = (DefTrackSVM*)m_Tracks.GetBlobByID(BlobID);
1420 return pF?pF->state:0.0f;
1422 /* return 0 if trajectory is normal
1423 return >0 if trajectory abnormal */
1424 virtual char* GetStateDesc(int BlobID)
1426 if(GetState(BlobID)>0.5) return "abnormal";
1429 virtual void SetFileName(char* DataBaseName)
1431 if(m_pTrainData)SaveStatModel();
1432 m_DataFileName[0] = 0;
1435 strncpy(m_DataFileName,DataBaseName,1000);
1436 strcat(m_DataFileName, ".yml");
1442 virtual void Release(){ delete this; };
1444 }; /* CvBlobTrackAnalysisSVM */
1447 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMP()
1448 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisSVM(cvCreateFVGenP);}
1449 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMPV()
1450 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisSVM(cvCreateFVGenPV);}
1451 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMPVS()
1452 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisSVM(cvCreateFVGenPVS);}
1453 CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMSS()
1454 {return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisSVM(cvCreateFVGenSS);}