/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // Intel License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000, Intel Corporation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of Intel Corporation may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ #ifndef __CVVIDEOSURVEILLANCE_H__ #define __CVVIDEOSURVEILLANCE_H__ /* Turn off the functionality until cvaux/src/Makefile.am gets updated: */ //#if _MSC_VER >= 1200 #include <stdio.h> #if _MSC_VER >= 1200 || defined __BORLANDC__ #define cv_stricmp stricmp #define cv_strnicmp strnicmp #elif defined __GNUC__ #define cv_stricmp strcasecmp #define cv_strnicmp strncasecmp #else #error Do not know how to make case-insensitive string comparison on this platform #endif //struct DefParam; struct CvDefParam { struct CvDefParam* next; char* pName; char* pComment; double* pDouble; double Double; float* pFloat; float Float; int* pInt; int Int; char** pStr; char* Str; }; class CV_EXPORTS CvVSModule { private: /* Internal data: */ CvDefParam* m_pParamList; char* m_pModuleTypeName; char* m_pModuleName; char* m_pNickName; protected: int m_Wnd; public: /* Constructor and destructor: */ CvVSModule() { m_pNickName = NULL; m_pParamList = NULL; m_pModuleTypeName = NULL; m_pModuleName = NULL; m_Wnd = 0; AddParam("DebugWnd",&m_Wnd); } virtual ~CvVSModule() { CvDefParam* p = m_pParamList; for(;p;) { CvDefParam* pf = p; p=p->next; FreeParam(&pf); } m_pParamList=NULL; if(m_pModuleTypeName)free(m_pModuleTypeName); if(m_pModuleName)free(m_pModuleName); } private: /* Internal functions: */ void FreeParam(CvDefParam** pp) { CvDefParam* p = pp[0]; if(p->Str)free(p->Str); if(p->pName)free(p->pName); if(p->pComment)free(p->pComment); cvFree((void**)pp); } CvDefParam* NewParam(const char* name) { CvDefParam* pNew = (CvDefParam*)cvAlloc(sizeof(CvDefParam)); memset(pNew,0,sizeof(CvDefParam)); pNew->pName = strdup(name); if(m_pParamList==NULL) { m_pParamList = pNew; } else { CvDefParam* p = m_pParamList; for(;p->next;p=p->next); p->next = pNew; } return pNew; }; CvDefParam* GetParamPtr(int index) { CvDefParam* p = m_pParamList; for(;index>0 && p;index--,p=p->next); return p; } CvDefParam* GetParamPtr(const char* name) { CvDefParam* p = m_pParamList; for(;p;p=p->next) { if(cv_stricmp(p->pName,name)==0) break; } return p; } protected: /* INTERNAL INTERFACE */ int IsParam(const char* name) { return GetParamPtr(name)?1:0; }; void AddParam(const char* name, double* pAddr) { NewParam(name)->pDouble = pAddr; }; void AddParam(const char* name, float* pAddr) { NewParam(name)->pFloat=pAddr; }; void AddParam(const char* name, int* pAddr) { NewParam(name)->pInt=pAddr; }; void AddParam(const char* name, char** pAddr) { CvDefParam* pP = NewParam(name); char* p = pAddr?pAddr[0]:NULL; pP->pStr = pAddr?pAddr:&(pP->Str); if(p) { pP->Str = strdup(p); pP->pStr[0] = pP->Str; } }; void AddParam(const char* name) { CvDefParam* p = NewParam(name); p->pDouble = &p->Double; }; void CommentParam(const char* name, const char* pComment) { CvDefParam* p = GetParamPtr(name); if(p)p->pComment = pComment ? strdup(pComment) : 0; }; void SetTypeName(const char* name){m_pModuleTypeName = strdup(name);} void SetModuleName(const char* name){m_pModuleName = strdup(name);} void DelParam(const char* name) { CvDefParam* p = m_pParamList; CvDefParam* pPrev = NULL; for(;p;p=p->next) { if(cv_stricmp(p->pName,name)==0) break; pPrev = p; } if(p) { if(pPrev) { pPrev->next = p->next; } else { m_pParamList = p->next; } FreeParam(&p); } }/* DelParam */ public: /* EXTERNAL INTERFACE */ char* GetParamName(int index) { CvDefParam* p = GetParamPtr(index); return p?p->pName:NULL; } char* GetParamComment(const char* name) { CvDefParam* p = GetParamPtr(name); if(p && p->pComment) return p->pComment; return NULL; } double GetParam(const char* name) { CvDefParam* p = GetParamPtr(name); if(p) { if(p->pDouble) return p->pDouble[0]; if(p->pFloat) return p->pFloat[0]; if(p->pInt) return p->pInt[0]; } return 0; }; const char* GetParamStr(const char* name) { CvDefParam* p = GetParamPtr(name); return p?p->Str:NULL; } void SetParam(const char* name, double val) { CvDefParam* p = m_pParamList; for(;p;p=p->next) { if(cv_stricmp(p->pName,name) != 0) continue; if(p->pDouble)p->pDouble[0] = val; if(p->pFloat)p->pFloat[0] = (float)val; if(p->pInt)p->pInt[0] = cvRound(val); } } void SetParamStr(const char* name, const char* str) { CvDefParam* p = m_pParamList; for(; p; p=p->next) { if(cv_stricmp(p->pName,name) != 0) continue; if(p->pStr) { if(p->Str)free(p->Str); p->Str = NULL; if(str)p->Str = strdup(str); p->pStr[0] = p->Str; } } /* Convert to double and set: */ if(str) SetParam(name,atof(str)); } void TransferParamsFromChild(CvVSModule* pM, char* prefix = NULL) { char tmp[1024]; char* FN = NULL; int i; for(i=0;;++i) { char* N = pM->GetParamName(i); if(N == NULL) break; FN = N; if(prefix) { strcpy(tmp,prefix); strcat(tmp,"_"); FN = strcat(tmp,N); } if(!IsParam(FN)) { if(pM->GetParamStr(N)) { AddParam(FN,(char**)NULL); } else { AddParam(FN); } } if(pM->GetParamStr(N)) { const char* val = pM->GetParamStr(N); SetParamStr(FN,val); } else { double val = pM->GetParam(N); SetParam(FN,val); } CommentParam(FN, pM->GetParamComment(N)); }/* transfer next param */ }/* Transfer params */ void TransferParamsToChild(CvVSModule* pM, char* prefix = NULL) { char tmp[1024]; int i; for(i=0;;++i) { char* N = pM->GetParamName(i); if(N == NULL) break; if(prefix) { strcpy(tmp,prefix); strcat(tmp,"_"); strcat(tmp,N); } else { strcpy(tmp,N); } if(IsParam(tmp)) { if(GetParamStr(tmp)) pM->SetParamStr(N,GetParamStr(tmp)); else pM->SetParam(N,GetParam(tmp)); } }/* Transfer next parameter */ pM->ParamUpdate(); }/* Transfer params */ virtual void ParamUpdate(){}; const char* GetTypeName() { return m_pModuleTypeName; } int IsModuleTypeName(const char* name) { return m_pModuleTypeName?(cv_stricmp(m_pModuleTypeName,name)==0):0; } char* GetModuleName() { return m_pModuleName; } int IsModuleName(const char* name) { return m_pModuleName?(cv_stricmp(m_pModuleName,name)==0):0; } void SetNickName(const char* pStr) { if(m_pNickName) free(m_pNickName); m_pNickName = NULL; if(pStr) m_pNickName = strdup(pStr); } const char* GetNickName() { return m_pNickName ? m_pNickName : "unknown"; } virtual void SaveState(CvFileStorage*){}; virtual void LoadState(CvFileStorage*, CvFileNode*){}; virtual void Release() = 0; };/* CvVMModule */ void inline cvWriteStruct(CvFileStorage* fs, const char* name, void* addr, char* desc, int num=1) { cvStartWriteStruct(fs,name,CV_NODE_SEQ|CV_NODE_FLOW); cvWriteRawData(fs,addr,num,desc); cvEndWriteStruct(fs); } void inline cvReadStructByName(CvFileStorage* fs, CvFileNode* node, const char* name, void* addr, char* desc) { CvFileNode* pSeqNode = cvGetFileNodeByName(fs, node, name); if(pSeqNode==NULL) { printf("WARNING!!! Can't read structure %s\n",name); } else { if(CV_NODE_IS_SEQ(pSeqNode->tag)) { cvReadRawData( fs, pSeqNode, addr, desc ); } else { printf("WARNING!!! Structure %s is not sequence and can not be read\n",name); } } } /* FOREGROUND DETECTOR INTERFACE */ class CV_EXPORTS CvFGDetector: public CvVSModule { public: virtual IplImage* GetMask() = 0; /* Process current image: */ virtual void Process(IplImage* pImg) = 0; /* Release foreground detector: */ virtual void Release() = 0; }; inline void cvReleaseFGDetector(CvFGDetector** ppT ) { ppT[0]->Release(); ppT[0] = 0; } /* FOREGROUND DETECTOR INTERFACE */ CV_EXPORTS CvFGDetector* cvCreateFGDetectorBase(int type, void *param); /* BLOB STRUCTURE*/ struct CvBlob { float x,y; /* blob position */ float w,h; /* blob sizes */ int ID; /* blob ID */ }; inline CvBlob cvBlob(float x,float y, float w, float h) { CvBlob B = {x,y,w,h,0}; return B; } #define CV_BLOB_MINW 5 #define CV_BLOB_MINH 5 #define CV_BLOB_ID(pB) (((CvBlob*)(pB))->ID) #define CV_BLOB_CENTER(pB) cvPoint2D32f(((CvBlob*)(pB))->x,((CvBlob*)(pB))->y) #define CV_BLOB_X(pB) (((CvBlob*)(pB))->x) #define CV_BLOB_Y(pB) (((CvBlob*)(pB))->y) #define CV_BLOB_WX(pB) (((CvBlob*)(pB))->w) #define CV_BLOB_WY(pB) (((CvBlob*)(pB))->h) #define CV_BLOB_RX(pB) (0.5f*CV_BLOB_WX(pB)) #define CV_BLOB_RY(pB) (0.5f*CV_BLOB_WY(pB)) #define CV_BLOB_RECT(pB) cvRect(cvRound(((CvBlob*)(pB))->x-CV_BLOB_RX(pB)),cvRound(((CvBlob*)(pB))->y-CV_BLOB_RY(pB)),cvRound(CV_BLOB_WX(pB)),cvRound(CV_BLOB_WY(pB))) /* END BLOB STRUCTURE*/ /* simple BLOBLIST */ class CV_EXPORTS CvBlobSeq { public: CvBlobSeq(int BlobSize = sizeof(CvBlob)) { m_pMem = cvCreateMemStorage(); m_pSeq = cvCreateSeq(0,sizeof(CvSeq),BlobSize,m_pMem); strcpy(m_pElemFormat,"ffffi"); } virtual ~CvBlobSeq() { cvReleaseMemStorage(&m_pMem); }; virtual CvBlob* GetBlob(int BlobIndex) { return (CvBlob*)cvGetSeqElem(m_pSeq,BlobIndex); }; virtual CvBlob* GetBlobByID(int BlobID) { int i; for(i=0; i<m_pSeq->total; ++i) if(BlobID == CV_BLOB_ID(GetBlob(i))) return GetBlob(i); return NULL; }; virtual void DelBlob(int BlobIndex) { cvSeqRemove(m_pSeq,BlobIndex); }; virtual void DelBlobByID(int BlobID) { int i; for(i=0; i<m_pSeq->total; ++i) { if(BlobID == CV_BLOB_ID(GetBlob(i))) { DelBlob(i); return; } } }; virtual void Clear() { cvClearSeq(m_pSeq); }; virtual void AddBlob(CvBlob* pB) { cvSeqPush(m_pSeq,pB); }; virtual int GetBlobNum() { return m_pSeq->total; }; virtual void Write(CvFileStorage* fs, const char* name) { const char* attr[] = {"dt",m_pElemFormat,NULL}; if(fs) { cvWrite(fs,name,m_pSeq,cvAttrList(attr,NULL)); } } virtual void Load(CvFileStorage* fs, CvFileNode* node) { if(fs==NULL) return; CvSeq* pSeq = (CvSeq*)cvRead(fs, node); if(pSeq) { int i; cvClearSeq(m_pSeq); for(i=0;i<pSeq->total;++i) { void* pB = cvGetSeqElem( pSeq, i ); cvSeqPush( m_pSeq, pB ); } } } void AddFormat(char* str){strcat(m_pElemFormat,str);} protected: CvMemStorage* m_pMem; CvSeq* m_pSeq; char m_pElemFormat[1024]; }; /* simple BLOBLIST */ /* simple TRACKLIST */ struct CvBlobTrack { int TrackID; int StartFrame; CvBlobSeq* pBlobSeq; }; class CV_EXPORTS CvBlobTrackSeq { public: CvBlobTrackSeq(int TrackSize = sizeof(CvBlobTrack)) { m_pMem = cvCreateMemStorage(); m_pSeq = cvCreateSeq(0,sizeof(CvSeq),TrackSize,m_pMem); } virtual ~CvBlobTrackSeq() { Clear(); cvReleaseMemStorage(&m_pMem); }; virtual CvBlobTrack* GetBlobTrack(int TrackIndex) { return (CvBlobTrack*)cvGetSeqElem(m_pSeq,TrackIndex); }; virtual CvBlobTrack* GetBlobTrackByID(int TrackID) { int i; for(i=0; i<m_pSeq->total; ++i) { CvBlobTrack* pP = GetBlobTrack(i); if(pP && pP->TrackID == TrackID) return pP; } return NULL; }; virtual void DelBlobTrack(int TrackIndex) { CvBlobTrack* pP = GetBlobTrack(TrackIndex); if(pP && pP->pBlobSeq) delete pP->pBlobSeq; cvSeqRemove(m_pSeq,TrackIndex); }; virtual void DelBlobTrackByID(int TrackID) { int i; for(i=0; i<m_pSeq->total; ++i) { CvBlobTrack* pP = GetBlobTrack(i); if(TrackID == pP->TrackID) { DelBlobTrack(i); return; } } }; virtual void Clear() { int i; for(i=GetBlobTrackNum();i>0;i--) { DelBlobTrack(i-1); } cvClearSeq(m_pSeq); }; virtual void AddBlobTrack(int TrackID, int StartFrame = 0) { CvBlobTrack N; N.TrackID = TrackID; N.StartFrame = StartFrame; N.pBlobSeq = new CvBlobSeq; cvSeqPush(m_pSeq,&N); }; virtual int GetBlobTrackNum() { return m_pSeq->total; }; protected: CvMemStorage* m_pMem; CvSeq* m_pSeq; }; /* simple TRACKLIST */ /* BLOB DETECTOR INTERFACE */ class CV_EXPORTS CvBlobDetector: public CvVSModule { public: /* Try to detect new blob entrance based on foreground mask. */ /* pFGMask - image of foreground mask */ /* pNewBlob - pointer to CvBlob structure which will be filled if new blob entrance detected */ /* pOldBlobList - pointer to blob list which already exist on image */ virtual int DetectNewBlob(IplImage* pImg, IplImage* pImgFG, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList) = 0; /* release blob detector */ virtual void Release()=0; }; /* Release any blob detector: */ inline void cvReleaseBlobDetector(CvBlobDetector** ppBD) { ppBD[0]->Release(); ppBD[0] = NULL; } /* END BLOB DETECTOR INTERFACE */ /* Declarations of constructors of implemented modules: */ CV_EXPORTS CvBlobDetector* cvCreateBlobDetectorSimple(); CV_EXPORTS CvBlobDetector* cvCreateBlobDetectorCC(); struct CV_EXPORTS CvDetectedBlob : public CvBlob { float response; }; CV_INLINE CvDetectedBlob cvDetectedBlob( float x, float y, float w, float h, int ID = 0, float response = 0.0F ) { CvDetectedBlob b; b.x = x; b.y = y; b.w = w; b.h = h; b.ID = ID; b.response = response; return b; } class CV_EXPORTS CvObjectDetector { public: CvObjectDetector( const char* /*detector_file_name*/ = 0 ) {}; ~CvObjectDetector() {}; /* * Release the current detector and load new detector from file * (if detector_file_name is not 0) * Return true on success: */ bool Load( const char* /*detector_file_name*/ = 0 ) { return false; } /* Return min detector window size: */ CvSize GetMinWindowSize() const { return cvSize(0,0); } /* Return max border: */ int GetMaxBorderSize() const { return 0; } /* * Detect the object on the image and push the detected * blobs into <detected_blob_seq> which must be the sequence of <CvDetectedBlob>s */ void Detect( const CvArr* /*img*/, /* out */ CvBlobSeq* /*detected_blob_seq*/ = 0 ) {}; protected: class CvObjectDetectorImpl* impl; }; CV_INLINE CvRect cvRectIntersection( const CvRect r1, const CvRect r2 ) { CvRect r = cvRect( MAX(r1.x, r2.x), MAX(r1.y, r2.y), 0, 0 ); r.width = MIN(r1.x + r1.width, r2.x + r2.width) - r.x; r.height = MIN(r1.y + r1.height, r2.y + r2.height) - r.y; return r; } /* * CvImageDrawer * * Draw on an image the specified ROIs from the source image and * given blobs as ellipses or rectangles: */ struct CvDrawShape { enum {RECT, ELLIPSE} shape; CvScalar color; }; /*extern const CvDrawShape icv_shape[] = { { CvDrawShape::ELLIPSE, CV_RGB(255,0,0) }, { CvDrawShape::ELLIPSE, CV_RGB(0,255,0) }, { CvDrawShape::ELLIPSE, CV_RGB(0,0,255) }, { CvDrawShape::ELLIPSE, CV_RGB(255,255,0) }, { CvDrawShape::ELLIPSE, CV_RGB(0,255,255) }, { CvDrawShape::ELLIPSE, CV_RGB(255,0,255) } };*/ class CV_EXPORTS CvImageDrawer { public: CvImageDrawer() : m_image(0) {} ~CvImageDrawer() { cvReleaseImage( &m_image ); } void SetShapes( const CvDrawShape* shapes, int num ); /* <blob_seq> must be the sequence of <CvDetectedBlob>s */ IplImage* Draw( const CvArr* src, CvBlobSeq* blob_seq = 0, const CvSeq* roi_seq = 0 ); IplImage* GetImage() { return m_image; } protected: //static const int MAX_SHAPES = sizeof(icv_shape) / sizeof(icv_shape[0]);; IplImage* m_image; CvDrawShape m_shape[16]; }; /* Trajectory generation module: */ class CV_EXPORTS CvBlobTrackGen: public CvVSModule { public: virtual void SetFileName(char* pFileName) = 0; virtual void AddBlob(CvBlob* pBlob) = 0; virtual void Process(IplImage* pImg = NULL, IplImage* pFG = NULL) = 0; virtual void Release() = 0; }; inline void cvReleaseBlobTrackGen(CvBlobTrackGen** pBTGen) { if(*pBTGen)(*pBTGen)->Release(); *pBTGen = 0; } /* Declarations of constructors of implemented modules: */ CV_EXPORTS CvBlobTrackGen* cvCreateModuleBlobTrackGen1(); CV_EXPORTS CvBlobTrackGen* cvCreateModuleBlobTrackGenYML(); /* BLOB TRACKER INTERFACE */ class CV_EXPORTS CvBlobTracker: public CvVSModule { public: CvBlobTracker(){SetTypeName("BlobTracker");}; /* Add new blob to track it and assign to this blob personal ID */ /* pBlob - pointer to structure with blob parameters (ID is ignored)*/ /* pImg - current image */ /* pImgFG - current foreground mask */ /* Return pointer to new added blob: */ virtual CvBlob* AddBlob(CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG = NULL ) = 0; /* Return number of currently tracked blobs: */ virtual int GetBlobNum() = 0; /* Return pointer to specified by index blob: */ virtual CvBlob* GetBlob(int BlobIndex) = 0; /* Delete blob by its index: */ virtual void DelBlob(int BlobIndex) = 0; /* Process current image and track all existed blobs: */ virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL) = 0; /* Release blob tracker: */ virtual void Release() = 0; /* Process one blob (for multi hypothesis tracing): */ virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL) { CvBlob* pB; int ID = 0; assert(pBlob); //pBlob->ID; pB = GetBlob(BlobIndex); if(pB) pBlob[0] = pB[0]; pBlob->ID = ID; }; /* Get confidence/wieght/probability (0-1) for blob: */ virtual double GetConfidence(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL) { return 1; }; virtual double GetConfidenceList(CvBlobSeq* pBlobList, IplImage* pImg, IplImage* pImgFG = NULL) { int b,bN = pBlobList->GetBlobNum(); double W = 1; for(b=0;b<bN;++b) { CvBlob* pB = pBlobList->GetBlob(b); int BI = GetBlobIndexByID(pB->ID); W *= GetConfidence(BI,pB,pImg,pImgFG); } return W; }; virtual void UpdateBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL){}; /* Update all blob models: */ virtual void Update(IplImage* pImg, IplImage* pImgFG = NULL) { int i; for(i=GetBlobNum();i>0;i--) { CvBlob* pB=GetBlob(i-1); UpdateBlob(i-1, pB, pImg, pImgFG); } }; /* Return pointer to blob by its unique ID: */ virtual int GetBlobIndexByID(int BlobID) { int i; for(i=GetBlobNum();i>0;i--) { CvBlob* pB=GetBlob(i-1); if(CV_BLOB_ID(pB) == BlobID) return i-1; } return -1; }; /* Return pointer to blob by its unique ID: */ virtual CvBlob* GetBlobByID(int BlobID){return GetBlob(GetBlobIndexByID(BlobID));}; /* Delete blob by its ID: */ virtual void DelBlobByID(int BlobID){DelBlob(GetBlobIndexByID(BlobID));}; /* Set new parameters for specified (by index) blob: */ virtual void SetBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/){}; /* Set new parameters for specified (by ID) blob: */ virtual void SetBlobByID(int BlobID, CvBlob* pBlob) { SetBlob(GetBlobIndexByID(BlobID),pBlob); }; /* =============== MULTI HYPOTHESIS INTERFACE ================== */ /* Return number of position hyposetis of currently tracked blob: */ virtual int GetBlobHypNum(int /*BlobIdx*/){return 1;}; /* Return pointer to specified blob hypothesis by index blob: */ virtual CvBlob* GetBlobHyp(int BlobIndex, int /*hypothesis*/){return GetBlob(BlobIndex);}; /* Set new parameters for specified (by index) blob hyp * (can be called several times for each hyp ): */ virtual void SetBlobHyp(int /*BlobIndex*/, CvBlob* /*pBlob*/){}; }; inline void cvReleaseBlobTracker(CvBlobTracker**ppT ) { ppT[0]->Release(); ppT[0] = 0; } /* BLOB TRACKER INTERFACE */ /*BLOB TRACKER ONE INTERFACE */ class CV_EXPORTS CvBlobTrackerOne:public CvVSModule { public: virtual void Init(CvBlob* pBlobInit, IplImage* pImg, IplImage* pImgFG = NULL) = 0; virtual CvBlob* Process(CvBlob* pBlobPrev, IplImage* pImg, IplImage* pImgFG = NULL) = 0; virtual void Release() = 0; /* Non-required methods: */ virtual void SkipProcess(CvBlob* /*pBlobPrev*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL){}; virtual void Update(CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL){}; virtual void SetCollision(int /*CollisionFlag*/){}; /* call in case of blob collision situation*/ virtual double GetConfidence(CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL, IplImage* /*pImgUnusedReg*/ = NULL) { return 1; }; }; inline void cvReleaseBlobTrackerOne(CvBlobTrackerOne **ppT ) { ppT[0]->Release(); ppT[0] = 0; } CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerList(CvBlobTrackerOne* (*create)()); /*BLOB TRACKER ONE INTERFACE */ /* Declarations of constructors of implemented modules: */ /* Some declarations for specific MeanShift tracker: */ #define PROFILE_EPANECHNIKOV 0 #define PROFILE_DOG 1 struct CvBlobTrackerParamMS { int noOfSigBits; int appearance_profile; int meanshift_profile; float sigma; }; CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMS1(CvBlobTrackerParamMS* param); CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMS2(CvBlobTrackerParamMS* param); CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMS1ByList(); /* Some declarations for specific Likelihood tracker: */ struct CvBlobTrackerParamLH { int HistType; /* see Prob.h */ int ScaleAfter; }; /* Without scale optimization: */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerLHR(CvBlobTrackerParamLH* /*param*/ = NULL); /* With scale optimization: */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerLHRS(CvBlobTrackerParamLH* /*param*/ = NULL); /* Simple blob tracker based on connected component tracking: */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerCC(); /* Connected component tracking and mean-shift particle filter collion-resolver: */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerCCMSPF(); /* Blob tracker that integrates meanshift and connected components: */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMSFG(); CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMSFGS(); /* Meanshift without connected-components */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMS(); /* Particle filtering via Bhattacharya coefficient, which */ /* is roughly the dot-product of two probability densities. */ /* See: Real-Time Tracking of Non-Rigid Objects using Mean Shift */ /* Comanicius, Ramesh, Meer, 2000, 8p */ /* http://citeseer.ist.psu.edu/321441.html */ CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerMSPF(); /* =========== tracker integrators trackers =============*/ /* Integrator based on Particle Filtering method: */ //CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerIPF(); /* Rule based integrator: */ //CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerIRB(); /* Integrator based on data fusion using particle filtering: */ //CV_EXPORTS CvBlobTracker* cvCreateBlobTrackerIPFDF(); /* Trajectory postprocessing module: */ class CV_EXPORTS CvBlobTrackPostProc: public CvVSModule { public: virtual void AddBlob(CvBlob* pBlob) = 0; virtual void Process() = 0; virtual int GetBlobNum() = 0; virtual CvBlob* GetBlob(int index) = 0; virtual void Release() = 0; /* Additional functionality: */ virtual CvBlob* GetBlobByID(int BlobID) { int i; for(i=GetBlobNum();i>0;i--) { CvBlob* pB=GetBlob(i-1); if(pB->ID==BlobID) return pB; } return NULL; }; }; inline void cvReleaseBlobTrackPostProc(CvBlobTrackPostProc** pBTPP) { if(pBTPP == NULL) return; if(*pBTPP)(*pBTPP)->Release(); *pBTPP = 0; } /* Trajectory generation module: */ class CV_EXPORTS CvBlobTrackPostProcOne: public CvVSModule { public: virtual CvBlob* Process(CvBlob* pBlob) = 0; virtual void Release() = 0; }; /* Create blob tracking post processing module based on simle module: */ CV_EXPORTS CvBlobTrackPostProc* cvCreateBlobTrackPostProcList(CvBlobTrackPostProcOne* (*create)()); /* Declarations of constructors of implemented modules: */ CV_EXPORTS CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcKalman(); CV_EXPORTS CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverRect(); CV_EXPORTS CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverExp(); /* PREDICTORS */ /* blob PREDICTOR */ class CvBlobTrackPredictor: public CvVSModule { public: virtual CvBlob* Predict() = 0; virtual void Update(CvBlob* pBlob) = 0; virtual void Release() = 0; }; CV_EXPORTS CvBlobTrackPredictor* cvCreateModuleBlobTrackPredictKalman(); /* Trajectory analyser module: */ class CV_EXPORTS CvBlobTrackAnalysis: public CvVSModule { public: virtual void AddBlob(CvBlob* pBlob) = 0; virtual void Process(IplImage* pImg, IplImage* pFG) = 0; virtual float GetState(int BlobID) = 0; /* return 0 if trajectory is normal return >0 if trajectory abnormal */ virtual char* GetStateDesc(int /*BlobID*/){return NULL;}; virtual void SetFileName(char* /*DataBaseName*/){}; virtual void Release() = 0; }; inline void cvReleaseBlobTrackAnalysis(CvBlobTrackAnalysis** pBTPP) { if(pBTPP == NULL) return; if(*pBTPP)(*pBTPP)->Release(); *pBTPP = 0; } /* Feature-vector generation module: */ class CV_EXPORTS CvBlobTrackFVGen : public CvVSModule { public: virtual void AddBlob(CvBlob* pBlob) = 0; virtual void Process(IplImage* pImg, IplImage* pFG) = 0; virtual void Release() = 0; virtual int GetFVSize() = 0; virtual int GetFVNum() = 0; virtual float* GetFV(int index, int* pFVID) = 0; /* Returns pointer to FV, if return 0 then FV not created */ virtual float* GetFVVar(){return NULL;}; /* Returns pointer to array of variation of values of FV, if returns 0 then FVVar does not exist. */ virtual float* GetFVMin() = 0; /* Returns pointer to array of minimal values of FV, if returns 0 then FVrange does not exist */ virtual float* GetFVMax() = 0; /* Returns pointer to array of maximal values of FV, if returns 0 then FVrange does not exist */ }; /* Trajectory Analyser module: */ class CV_EXPORTS CvBlobTrackAnalysisOne { public: virtual ~CvBlobTrackAnalysisOne() {}; virtual int Process(CvBlob* pBlob, IplImage* pImg, IplImage* pFG) = 0; /* return 0 if trajectory is normal return >0 if trajectory abnormal */ virtual void Release() = 0; }; /* Create blob tracking post processing module based on simle module: */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateBlobTrackAnalysisList(CvBlobTrackAnalysisOne* (*create)()); /* Declarations of constructors of implemented modules: */ /* Based on histogram analysis of 2D FV (x,y): */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistP(); /* Based on histogram analysis of 4D FV (x,y,vx,vy): */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPV(); /* Based on histogram analysis of 5D FV (x,y,vx,vy,state): */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPVS(); /* Based on histogram analysis of 4D FV (startpos,stoppos): */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistSS(); /* Based on SVM classifier analysis of 2D FV (x,y): */ //CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMP(); /* Based on SVM classifier analysis of 4D FV (x,y,vx,vy): */ //CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMPV(); /* Based on SVM classifier analysis of 5D FV (x,y,vx,vy,state): */ //CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMPVS(); /* Based on SVM classifier analysis of 4D FV (startpos,stoppos): */ //CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisSVMSS(); /* Track analysis based on distance between tracks: */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisTrackDist(); /* Analyzer based on reation Road and height map: */ //CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysis3DRoadMap(); /* Analyzer that makes OR decision using set of analyzers: */ CV_EXPORTS CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisIOR(); /* Estimator of human height: */ class CV_EXPORTS CvBlobTrackAnalysisHeight: public CvBlobTrackAnalysis { public: virtual double GetHeight(CvBlob* pB) = 0; }; //CV_EXPORTS CvBlobTrackAnalysisHeight* cvCreateModuleBlobTrackAnalysisHeightScale(); /* AUTO BLOB TRACKER INTERFACE -- pipeline of 3 modules: */ class CV_EXPORTS CvBlobTrackerAuto: public CvVSModule { public: virtual void Process(IplImage* pImg, IplImage* pMask = NULL) = 0; virtual CvBlob* GetBlob(int index) = 0; virtual CvBlob* GetBlobByID(int ID) = 0; virtual int GetBlobNum() = 0; virtual IplImage* GetFGMask(){return NULL;}; virtual float GetState(int BlobID) = 0; virtual char* GetStateDesc(int BlobID) = 0; /* return 0 if trajectory is normal; * return >0 if trajectory abnormal. */ virtual void Release() = 0; }; inline void cvReleaseBlobTrackerAuto(CvBlobTrackerAuto** ppT) { ppT[0]->Release(); ppT[0] = 0; } /* END AUTO BLOB TRACKER INTERFACE */ /* Constructor functions and data for specific BlobTRackerAuto modules: */ /* Parameters of blobtracker auto ver1: */ struct CvBlobTrackerAutoParam1 { int FGTrainFrames; /* Number of frames needed for FG (foreground) detector to train. */ CvFGDetector* pFG; /* FGDetector module. If this field is NULL the Process FG mask is used. */ CvBlobDetector* pBD; /* Selected blob detector module. */ /* If this field is NULL default blobdetector module will be created. */ CvBlobTracker* pBT; /* Selected blob tracking module. */ /* If this field is NULL default blobtracker module will be created. */ CvBlobTrackGen* pBTGen; /* Selected blob trajectory generator. */ /* If this field is NULL no generator is used. */ CvBlobTrackPostProc* pBTPP; /* Selected blob trajectory postprocessing module. */ /* If this field is NULL no postprocessing is done. */ int UsePPData; CvBlobTrackAnalysis* pBTA; /* Selected blob trajectory analysis module. */ /* If this field is NULL no track analysis is done. */ }; /* Create blob tracker auto ver1: */ CV_EXPORTS CvBlobTrackerAuto* cvCreateBlobTrackerAuto1(CvBlobTrackerAutoParam1* param = NULL); /* Simple loader for many auto trackers by its type : */ inline CvBlobTrackerAuto* cvCreateBlobTrackerAuto(int type, void* param) { if(type == 0) return cvCreateBlobTrackerAuto1((CvBlobTrackerAutoParam1*)param); return 0; } struct CvTracksTimePos { int len1,len2; int beg1,beg2; int end1,end2; int comLen; //common length for two tracks int shift1,shift2; }; /*CV_EXPORTS int cvCompareTracks( CvBlobTrackSeq *groundTruth, CvBlobTrackSeq *result, FILE *file);*/ /* Constructor functions: */ CV_EXPORTS void cvCreateTracks_One(CvBlobTrackSeq *TS); CV_EXPORTS void cvCreateTracks_Same(CvBlobTrackSeq *TS1, CvBlobTrackSeq *TS2); CV_EXPORTS void cvCreateTracks_AreaErr(CvBlobTrackSeq *TS1, CvBlobTrackSeq *TS2, int addW, int addH); /* HIST API */ class CV_EXPORTS CvProb { public: virtual ~CvProb() {}; /* Calculate probability value: */ virtual double Value(int* /*comp*/, int /*x*/ = 0, int /*y*/ = 0){return -1;}; /* Update histograpp Pnew = (1-W)*Pold + W*Padd*/ /* W weight of new added prob */ /* comps - matrix of new fetature vectors used to update prob */ virtual void AddFeature(float W, int* comps, int x =0, int y = 0) = 0; virtual void Scale(float factor = 0, int x = -1, int y = -1) = 0; virtual void Release() = 0; }; inline void cvReleaseProb(CvProb** ppProb){ppProb[0]->Release();ppProb[0]=NULL;} /* HIST API */ /* Some Prob: */ CV_EXPORTS CvProb* cvCreateProbS(int dim, CvSize size, int sample_num); CV_EXPORTS CvProb* cvCreateProbMG(int dim, CvSize size, int sample_num); CV_EXPORTS CvProb* cvCreateProbMG2(int dim, CvSize size, int sample_num); CV_EXPORTS CvProb* cvCreateProbHist(int dim, CvSize size); #define CV_BT_HIST_TYPE_S 0 #define CV_BT_HIST_TYPE_MG 1 #define CV_BT_HIST_TYPE_MG2 2 #define CV_BT_HIST_TYPE_H 3 inline CvProb* cvCreateProb(int type, int dim, CvSize size = cvSize(1,1), void* /*param*/ = NULL) { if(type == CV_BT_HIST_TYPE_S) return cvCreateProbS(dim, size, -1); if(type == CV_BT_HIST_TYPE_MG) return cvCreateProbMG(dim, size, -1); if(type == CV_BT_HIST_TYPE_MG2) return cvCreateProbMG2(dim, size, -1); if(type == CV_BT_HIST_TYPE_H) return cvCreateProbHist(dim, size); return NULL; } /* Noise type definitions: */ #define CV_NOISE_NONE 0 #define CV_NOISE_GAUSSIAN 1 #define CV_NOISE_UNIFORM 2 #define CV_NOISE_SPECKLE 3 #define CV_NOISE_SALT_AND_PEPPER 4 /* Add some noise to image: */ /* pImg - (input) image without noise */ /* pImg - (output) image with noise */ /* noise_type - type of added noise */ /* CV_NOISE_GAUSSIAN - pImg += n , n - is gaussian noise with Ampl standart deviation */ /* CV_NOISE_UNIFORM - pImg += n , n - is uniform noise with Ampl standart deviation */ /* CV_NOISE_SPECKLE - pImg += n*pImg , n - is gaussian noise with Ampl standart deviation */ /* CV_NOISE_SALT_AND_PAPPER - pImg = pImg with blacked and whited pixels, Ampl is density of brocken pixels (0-there are not broken pixels, 1 - all pixels are broken)*/ /* Ampl - "amplitude" of noise */ CV_EXPORTS void cvAddNoise(IplImage* pImg, int noise_type, double Ampl, CvRandState* rnd_state = NULL); /*================== GENERATOR OF TEST VIDEO SEQUENCE ===================== */ typedef void CvTestSeq; /* pConfigfile - Name of file (yml or xml) with description of test sequence */ /* videos - array of names of test videos described in "pConfigfile" file */ /* numvideos - size of "videos" array */ CV_EXPORTS CvTestSeq* cvCreateTestSeq(char* pConfigfile, char** videos, int numvideo, float Scale = 1, int noise_type = CV_NOISE_NONE, double noise_ampl = 0); CV_EXPORTS void cvReleaseTestSeq(CvTestSeq** ppTestSeq); /* Generate next frame from test video seq and return pointer to it: */ CV_EXPORTS IplImage* cvTestSeqQueryFrame(CvTestSeq* pTestSeq); /* Return pointer to current foreground mask: */ CV_EXPORTS IplImage* cvTestSeqGetFGMask(CvTestSeq* pTestSeq); /* Return pointer to current image: */ CV_EXPORTS IplImage* cvTestSeqGetImage(CvTestSeq* pTestSeq); /* Return frame size of result test video: */ CV_EXPORTS CvSize cvTestSeqGetImageSize(CvTestSeq* pTestSeq); /* Return number of frames result test video: */ CV_EXPORTS int cvTestSeqFrameNum(CvTestSeq* pTestSeq); /* Return number of existing objects. * This is general number of any objects. * For example number of trajectories may be equal or less than returned value: */ CV_EXPORTS int cvTestSeqGetObjectNum(CvTestSeq* pTestSeq); /* Return 0 if there is not position for current defined on current frame */ /* Return 1 if there is object position and pPos was filled */ CV_EXPORTS int cvTestSeqGetObjectPos(CvTestSeq* pTestSeq, int ObjIndex, CvPoint2D32f* pPos); CV_EXPORTS int cvTestSeqGetObjectSize(CvTestSeq* pTestSeq, int ObjIndex, CvPoint2D32f* pSize); /* Add noise to final image: */ CV_EXPORTS void cvTestSeqAddNoise(CvTestSeq* pTestSeq, int noise_type = CV_NOISE_NONE, double noise_ampl = 0); /* Add Intensity variation: */ CV_EXPORTS void cvTestSeqAddIntensityVariation(CvTestSeq* pTestSeq, float DI_per_frame, float MinI, float MaxI); CV_EXPORTS void cvTestSeqSetFrame(CvTestSeq* pTestSeq, int n); #endif /* End of file. */