moved some old stuff to the legacy module; merge "compat_c.h" headers and moved to the legacy as well. moved implementation of many non-critical/obsolete inline functions and methods to .cpp to improve Opencv build time

This commit is contained in:
Vadim Pisarevsky
2010-11-26 17:58:20 +00:00
parent fbdb4f4ab5
commit 54ef4c08c2
32 changed files with 1661 additions and 1289 deletions

View File

@@ -0,0 +1,211 @@
/*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
//
// 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*/
#include "precomp.hpp"
// Function cvCreateBGStatModel creates and returns initialized BG model.
// Parameters:
// first_frame - frame from video sequence
// model_type ñ type of BG model (CV_BG_MODEL_MOG, CV_BG_MODEL_FGD,Ö)
// parameters - (optional) if NULL the default parameters of the algorithm will be used
static CvBGStatModel* cvCreateBGStatModel( IplImage* first_frame, int model_type, void* params )
{
CvBGStatModel* bg_model = NULL;
if( model_type == CV_BG_MODEL_FGD || model_type == CV_BG_MODEL_FGD_SIMPLE )
bg_model = cvCreateFGDStatModel( first_frame, (CvFGDStatModelParams*)params );
else if( model_type == CV_BG_MODEL_MOG )
bg_model = cvCreateGaussianBGModel( first_frame, (CvGaussBGStatModelParams*)params );
return bg_model;
}
/* FOREGROUND DETECTOR INTERFACE */
class CvFGDetectorBase : public CvFGDetector
{
protected:
CvBGStatModel* m_pFG;
int m_FGType;
void* m_pFGParam; /* Foreground parameters. */
CvFGDStatModelParams m_ParamFGD;
CvGaussBGStatModelParams m_ParamMOG;
const char* m_SaveName;
const char* m_LoadName;
public:
virtual void SaveState(CvFileStorage* )
{
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if( m_SaveName ) /* File name is not empty */
{
//cvSaveStatModel(m_SaveName, (CvFGDStatModel*)m_pFG);
}
}
};
virtual void LoadState(CvFileStorage* , CvFileNode* )
{
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if( m_LoadName ) /* File name is not empty */
{
//cvRestoreStatModel(m_LoadName, (CvFGDStatModel*)m_pFG);
}
}
};
CvFGDetectorBase(int type, void* param)
{
m_pFG = NULL;
m_FGType = type;
m_pFGParam = param;
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if(m_pFGParam)
{
m_ParamFGD = *(CvFGDStatModelParams*)m_pFGParam;
}
else
{
m_ParamFGD.Lc = CV_BGFG_FGD_LC;
m_ParamFGD.N1c = CV_BGFG_FGD_N1C;
m_ParamFGD.N2c = CV_BGFG_FGD_N2C;
m_ParamFGD.Lcc = CV_BGFG_FGD_LCC;
m_ParamFGD.N1cc = CV_BGFG_FGD_N1CC;
m_ParamFGD.N2cc = CV_BGFG_FGD_N2CC;
m_ParamFGD.delta = CV_BGFG_FGD_DELTA;
m_ParamFGD.alpha1 = CV_BGFG_FGD_ALPHA_1;
m_ParamFGD.alpha2 = CV_BGFG_FGD_ALPHA_2;
m_ParamFGD.alpha3 = CV_BGFG_FGD_ALPHA_3;
m_ParamFGD.T = CV_BGFG_FGD_T;
m_ParamFGD.minArea = CV_BGFG_FGD_MINAREA;
m_ParamFGD.is_obj_without_holes = 1;
m_ParamFGD.perform_morphing = 1;
}
AddParam("LC",&m_ParamFGD.Lc);
AddParam("alpha1",&m_ParamFGD.alpha1);
AddParam("alpha2",&m_ParamFGD.alpha2);
AddParam("alpha3",&m_ParamFGD.alpha3);
AddParam("N1c",&m_ParamFGD.N1c);
AddParam("N2c",&m_ParamFGD.N2c);
AddParam("N1cc",&m_ParamFGD.N1cc);
AddParam("N2cc",&m_ParamFGD.N2cc);
m_SaveName = 0;
m_LoadName = 0;
AddParam("SaveName",&m_SaveName);
AddParam("LoadName",&m_LoadName);
AddParam("ObjWithoutHoles",&m_ParamFGD.is_obj_without_holes);
AddParam("Morphology",&m_ParamFGD.perform_morphing);
SetModuleName("FGD");
}
else if( m_FGType == CV_BG_MODEL_MOG ) // "MOG" == "Mixture Of Gaussians"
{
if(m_pFGParam)
{
m_ParamMOG = *(CvGaussBGStatModelParams*)m_pFGParam;
}
else
{ // These constants are all from cvaux/include/cvaux.h
m_ParamMOG.win_size = CV_BGFG_MOG_WINDOW_SIZE;
m_ParamMOG.bg_threshold = CV_BGFG_MOG_BACKGROUND_THRESHOLD;
m_ParamMOG.std_threshold = CV_BGFG_MOG_STD_THRESHOLD;
m_ParamMOG.weight_init = CV_BGFG_MOG_WEIGHT_INIT;
m_ParamMOG.variance_init = CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;
m_ParamMOG.minArea = CV_BGFG_MOG_MINAREA;
m_ParamMOG.n_gauss = CV_BGFG_MOG_NGAUSSIANS;
}
AddParam("NG",&m_ParamMOG.n_gauss);
SetModuleName("MOG");
}
};
~CvFGDetectorBase()
{
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
}
void ParamUpdate()
{
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
}
inline IplImage* GetMask()
{
return m_pFG?m_pFG->foreground:NULL;
};
/* Process current image: */
virtual void Process(IplImage* pImg)
{
if(m_pFG == NULL)
{
void* param = m_pFGParam;
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
param = &m_ParamFGD;
}
else if( m_FGType == CV_BG_MODEL_MOG )
{
param = &m_ParamMOG;
}
m_pFG = cvCreateBGStatModel(
pImg,
m_FGType,
param);
LoadState(0, 0);
}
else
{
cvUpdateBGStatModel( pImg, m_pFG );
}
};
/* Release foreground detector: */
virtual void Release()
{
SaveState(0);
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
};
};
CvFGDetector* cvCreateFGDetectorBase(int type, void *param)
{
return (CvFGDetector*) new CvFGDetectorBase(type, param);
}

View File

@@ -0,0 +1,640 @@
/*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.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2010, Willow Garage Inc., 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 names of the copyright holders 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*/
#include "precomp.hpp"
//////////////////////////// CvVSModule /////////////////////////////
CvVSModule::CvVSModule()
{
m_pNickName = NULL;
m_pParamList = NULL;
m_pModuleTypeName = NULL;
m_pModuleName = NULL;
m_Wnd = 0;
AddParam("DebugWnd",&m_Wnd);
}
CvVSModule::~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);
}
void CvVSModule::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(pp);
}
CvDefParam* CvVSModule::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* CvVSModule::GetParamPtr(int index)
{
CvDefParam* p = m_pParamList;
for(;index>0 && p;index--,p=p->next) ;
return p;
}
CvDefParam* CvVSModule::GetParamPtr(const char* name)
{
CvDefParam* p = m_pParamList;
for(;p;p=p->next)
{
if(cv_stricmp(p->pName,name)==0) break;
}
return p;
}
int CvVSModule::IsParam(const char* name)
{
return GetParamPtr(name)?1:0;
}
void CvVSModule::AddParam(const char* name, double* pAddr)
{
NewParam(name)->pDouble = pAddr;
}
void CvVSModule::AddParam(const char* name, float* pAddr)
{
NewParam(name)->pFloat=pAddr;
}
void CvVSModule::AddParam(const char* name, int* pAddr)
{
NewParam(name)->pInt=pAddr;
}
void CvVSModule::AddParam(const char* name, const char** pAddr)
{
CvDefParam* pP = NewParam(name);
const char* p = pAddr?pAddr[0]:NULL;
pP->pStr = pAddr?(char**)pAddr:&(pP->Str);
if(p)
{
pP->Str = strdup(p);
pP->pStr[0] = pP->Str;
}
}
void CvVSModule::AddParam(const char* name)
{
CvDefParam* p = NewParam(name);
p->pDouble = &p->Double;
}
void CvVSModule::CommentParam(const char* name, const char* pComment)
{
CvDefParam* p = GetParamPtr(name);
if(p)p->pComment = pComment ? strdup(pComment) : 0;
}
void CvVSModule::SetTypeName(const char* name){m_pModuleTypeName = strdup(name);}
void CvVSModule::SetModuleName(const char* name){m_pModuleName = strdup(name);}
void CvVSModule::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 */
const char* CvVSModule::GetParamName(int index)
{
CvDefParam* p = GetParamPtr(index);
return p?p->pName:NULL;
}
const char* CvVSModule::GetParamComment(const char* name)
{
CvDefParam* p = GetParamPtr(name);
if(p && p->pComment) return p->pComment;
return NULL;
}
double CvVSModule::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* CvVSModule::GetParamStr(const char* name)
{
CvDefParam* p = GetParamPtr(name);
return p?p->Str:NULL;
}
void CvVSModule::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 CvVSModule::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 CvVSModule::TransferParamsFromChild(CvVSModule* pM, const char* prefix)
{
char tmp[1024];
const char* FN = NULL;
int i;
for(i=0;;++i)
{
const 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,(const 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 CvVSModule::TransferParamsToChild(CvVSModule* pM, char* prefix)
{
char tmp[1024];
int i;
for(i=0;;++i)
{
const 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 */
void CvVSModule::ParamUpdate(){}
const char* CvVSModule::GetTypeName()
{
return m_pModuleTypeName;
}
int CvVSModule::IsModuleTypeName(const char* name)
{
return m_pModuleTypeName?(cv_stricmp(m_pModuleTypeName,name)==0):0;
}
char* CvVSModule::GetModuleName()
{
return m_pModuleName;
}
int CvVSModule::IsModuleName(const char* name)
{
return m_pModuleName?(cv_stricmp(m_pModuleName,name)==0):0;
}
void CvVSModule::SetNickName(const char* pStr)
{
if(m_pNickName)
free(m_pNickName);
m_pNickName = NULL;
if(pStr)
m_pNickName = strdup(pStr);
}
const char* CvVSModule::GetNickName()
{
return m_pNickName ? m_pNickName : "unknown";
}
void CvVSModule::SaveState(CvFileStorage*)
{
}
void CvVSModule::LoadState(CvFileStorage*, CvFileNode*)
{
}
/////////////////////////////////////////////////////////////////////
void cvWriteStruct(CvFileStorage* fs, const char* name, void* addr, const char* desc, int num)
{
cvStartWriteStruct(fs,name,CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,addr,num,desc);
cvEndWriteStruct(fs);
}
void cvReadStructByName(CvFileStorage* fs, CvFileNode* node, const char* name, void* addr, const 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);
}
}
}
////////////////////////////// CvFGDetector ///////////////////////////////////////////
CvFGDetector::CvFGDetector()
{
SetTypeName("FGDetector");
}
void cvReleaseFGDetector(CvFGDetector** ppT )
{
ppT[0]->Release();
ppT[0] = 0;
}
///////////////////////////// CvBlobSeq ///////////////////////////////////////////////
CvBlobTrackSeq::CvBlobTrackSeq(int TrackSize)
{
m_pMem = cvCreateMemStorage();
m_pSeq = cvCreateSeq(0,sizeof(CvSeq),TrackSize,m_pMem);
}
CvBlobTrackSeq::~CvBlobTrackSeq()
{
Clear();
cvReleaseMemStorage(&m_pMem);
}
CvBlobTrack* CvBlobTrackSeq::GetBlobTrack(int TrackIndex)
{
return (CvBlobTrack*)cvGetSeqElem(m_pSeq,TrackIndex);
}
CvBlobTrack* CvBlobTrackSeq::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;
}
void CvBlobTrackSeq::DelBlobTrack(int TrackIndex)
{
CvBlobTrack* pP = GetBlobTrack(TrackIndex);
if(pP && pP->pBlobSeq) delete pP->pBlobSeq;
cvSeqRemove(m_pSeq,TrackIndex);
}
void CvBlobTrackSeq::DelBlobTrackByID(int TrackID)
{
int i;
for(i=0; i<m_pSeq->total; ++i)
{
CvBlobTrack* pP = GetBlobTrack(i);
if(TrackID == pP->TrackID)
{
DelBlobTrack(i);
return;
}
}
}
void CvBlobTrackSeq::Clear()
{
int i;
for(i=GetBlobTrackNum();i>0;i--)
{
DelBlobTrack(i-1);
}
cvClearSeq(m_pSeq);
}
void CvBlobTrackSeq::AddBlobTrack(int TrackID, int StartFrame)
{
CvBlobTrack N;
N.TrackID = TrackID;
N.StartFrame = StartFrame;
N.pBlobSeq = new CvBlobSeq;
cvSeqPush(m_pSeq,&N);
}
int CvBlobTrackSeq::GetBlobTrackNum()
{
return m_pSeq->total;
}
void cvReleaseBlobDetector(CvBlobDetector** ppBD)
{
ppBD[0]->Release();
ppBD[0] = NULL;
}
///////////////////////////////////// CvObjectDetector /////////////////////////////////
CvObjectDetector::CvObjectDetector( const char* /*detector_file_name*/ )
{
}
CvObjectDetector::~CvObjectDetector()
{
}
/*
* Release the current detector and load new detector from file
* (if detector_file_name is not 0)
* Return true on success:
*/
bool CvObjectDetector::Load( const char* /*detector_file_name*/ )
{
return false;
}
/* Return min detector window size: */
CvSize CvObjectDetector::GetMinWindowSize() const
{
return cvSize(0,0);
}
/* Return max border: */
int CvObjectDetector::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 CvObjectDetector::Detect( const CvArr* /*img*/,
/* out */ CvBlobSeq* /*detected_blob_seq*/ )
{
}
//////////////////////////////// CvBlobTracker //////////////////////////////////////
CvBlobTracker::CvBlobTracker(){SetTypeName("BlobTracker");}
/* Process one blob (for multi hypothesis tracing): */
void CvBlobTracker::ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
{
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: */
double CvBlobTracker::GetConfidence(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
{
return 1;
}
double CvBlobTracker::GetConfidenceList(CvBlobSeq* pBlobList, IplImage* pImg, IplImage* pImgFG)
{
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;
}
void CvBlobTracker::UpdateBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* /*pImgFG*/)
{
}
/* Update all blob models: */
void CvBlobTracker::Update(IplImage* pImg, IplImage* pImgFG)
{
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: */
int CvBlobTracker::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: */
CvBlob* CvBlobTracker::GetBlobByID(int BlobID)
{
return GetBlob(GetBlobIndexByID(BlobID));
}
/* Delete blob by its ID: */
void CvBlobTracker::DelBlobByID(int BlobID)
{
DelBlob(GetBlobIndexByID(BlobID));
}
/* Set new parameters for specified (by index) blob: */
void CvBlobTracker::SetBlob(int /*BlobIndex*/, CvBlob* /*pBlob*/)
{
}
/* Set new parameters for specified (by ID) blob: */
void CvBlobTracker::SetBlobByID(int BlobID, CvBlob* pBlob)
{
SetBlob(GetBlobIndexByID(BlobID),pBlob);
}
/* =============== MULTI HYPOTHESIS INTERFACE ================== */
/* Return number of position hyposetis of currently tracked blob: */
int CvBlobTracker::GetBlobHypNum(int /*BlobIdx*/)
{
return 1;
}
/* Return pointer to specified blob hypothesis by index blob: */
CvBlob* CvBlobTracker::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 ):
*/
void CvBlobTracker::SetBlobHyp(int /*BlobIndex*/, CvBlob* /*pBlob*/)
{
}
void cvReleaseBlobTracker(CvBlobTracker**ppT )
{
ppT[0]->Release();
ppT[0] = 0;
}

View File

@@ -0,0 +1,128 @@
/*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*/
#include "precomp.hpp"
/*======================= FILTER LIST SHELL =====================*/
typedef struct DefTrackAnalyser
{
CvBlob blob;
CvBlobTrackAnalysisOne* pFilter;
int m_LastFrame;
int state;
} DefTrackAnalyser;
class CvBlobTrackAnalysisList : public CvBlobTrackAnalysis
{
protected:
CvBlobTrackAnalysisOne* (*m_CreateAnalysis)();
CvBlobSeq m_TrackAnalyserList;
int m_Frame;
public:
CvBlobTrackAnalysisList(CvBlobTrackAnalysisOne* (*create)()):m_TrackAnalyserList(sizeof(DefTrackAnalyser))
{
m_Frame = 0;
m_CreateAnalysis = create;
SetModuleName("List");
}
~CvBlobTrackAnalysisList()
{
int i;
for(i=m_TrackAnalyserList.GetBlobNum(); i>0; --i)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlob(i-1);
pF->pFilter->Release();
}
};
virtual void AddBlob(CvBlob* pBlob)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* Create new filter: */
DefTrackAnalyser F;
F.state = 0;
F.blob = pBlob[0];
F.m_LastFrame = m_Frame;
F.pFilter = m_CreateAnalysis();
m_TrackAnalyserList.AddBlob((CvBlob*)&F);
pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
pF->blob = pBlob[0];
pF->m_LastFrame = m_Frame;
};
virtual void Process(IplImage* pImg, IplImage* pFG)
{
int i;
for(i=m_TrackAnalyserList.GetBlobNum(); i>0; --i)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlob(i-1);
if(pF->m_LastFrame == m_Frame)
{ /* Process: */
int ID = CV_BLOB_ID(pF);
pF->state = pF->pFilter->Process(&(pF->blob), pImg, pFG);
CV_BLOB_ID(pF) = ID;
}
else
{ /* Delete blob filter: */
pF->pFilter->Release();
m_TrackAnalyserList.DelBlob(i-1);
}
} /* Next blob. */
m_Frame++;
};
float GetState(int BlobID)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(BlobID);
return pF?pF->state:0.f;
};
void Release(){delete this;};
}; /* CvBlobTrackAnalysisList */
CvBlobTrackAnalysis* cvCreateBlobTrackAnalysisList(CvBlobTrackAnalysisOne* (*create)())
{
return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisList(create);
}
/* ======================== Analyser modules ============================= */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
/*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*/
#include "precomp.hpp"
/*======================= FILTER LIST SHELL =====================*/
#define MAX_ANS 16
#define MAX_DESC 1024
class CvBlobTrackAnalysisIOR : public CvBlobTrackAnalysis
{
protected:
struct DefAn
{
const char* pName;
CvBlobTrackAnalysis* pAn;
} m_Ans[MAX_ANS];
int m_AnNum;
char m_Desc[MAX_DESC];
public:
CvBlobTrackAnalysisIOR()
{
m_AnNum = 0;
SetModuleName("IOR");
}
~CvBlobTrackAnalysisIOR()
{
};
virtual void AddBlob(CvBlob* pBlob)
{
int i;
for(i=0; i<m_AnNum; ++i)
{
m_Ans[i].pAn->AddBlob(pBlob);
} /* Next analyzer. */
};
virtual void Process(IplImage* pImg, IplImage* pFG)
{
int i;
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(i=0; i<m_AnNum; ++i)
{
m_Ans[i].pAn->Process(pImg, pFG);
} /* Next analyzer. */
};
float GetState(int BlobID)
{
int state = 0;
int i;
for(i=0; i<m_AnNum; ++i)
{
state |= (m_Ans[i].pAn->GetState(BlobID) > 0.5);
} /* Next analyzer. */
return (float)state;
};
virtual const char* GetStateDesc(int BlobID)
{
int rest = MAX_DESC-1;
int i;
m_Desc[0] = 0;
for(i=0; i<m_AnNum; ++i)
{
const char* str = m_Ans[i].pAn->GetStateDesc(BlobID);
if(str && strlen(m_Ans[i].pName) + strlen(str)+4 < (size_t)rest)
{
strcat(m_Desc,m_Ans[i].pName);
strcat(m_Desc,": ");
strcat(m_Desc,str);
strcat(m_Desc,"\n");
rest = MAX_DESC - (int)strlen(m_Desc) - 1;
}
} /* Next analyzer. */
if(m_Desc[0]!=0)return m_Desc;
return NULL;
};
virtual void SetFileName(char* /*DataBaseName*/)
{
};
int AddAnalyzer(CvBlobTrackAnalysis* pA, const char* pName)
{
if(m_AnNum<MAX_ANS)
{
//int i;
m_Ans[m_AnNum].pName = pName;
m_Ans[m_AnNum].pAn = pA;
TransferParamsFromChild(m_Ans[m_AnNum].pAn, pName);
m_AnNum++;
return 1;
}
else
{
printf("Can not add track analyzer %s! (not more that %d analyzers)\n",pName,MAX_ANS);
return 0;
}
}
void Release()
{
int i;
for(i=0; i<m_AnNum; ++i)
{
m_Ans[i].pAn->Release();
} /* Next analyzer. */
delete this;
};
}; /* CvBlobTrackAnalysisIOR. */
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisIOR()
{
CvBlobTrackAnalysisIOR* pIOR = new CvBlobTrackAnalysisIOR();
CvBlobTrackAnalysis* pA = NULL;
pA = cvCreateModuleBlobTrackAnalysisHistPVS();
pIOR->AddAnalyzer(pA, "HIST");
//pA = (CvBlobTrackAnalysis*)cvCreateModuleBlobTrackAnalysisHeightScale();
//pIOR->AddAnalyzer(pA, "SCALE");
return (CvBlobTrackAnalysis*)pIOR;
}/* cvCreateCvBlobTrackAnalysisIOR */
/* ======================== Analyser modules ============================= */

View File

@@ -0,0 +1,583 @@
/*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*/
#include "precomp.hpp"
typedef struct DefTrackPoint
{
float x,y,r,vx,vy,v;
} DefTrackPoint;
class DefTrackRec
{
private:
int ID;
public:
DefTrackRec(int id = 0,int BlobSize = sizeof(DefTrackPoint))
{
ID = id;
m_pMem = cvCreateMemStorage();
m_pSeq = cvCreateSeq(0,sizeof(CvSeq),BlobSize,m_pMem);
}
~DefTrackRec()
{
cvReleaseMemStorage(&m_pMem);
};
inline DefTrackPoint* GetPoint(int PointIndex)
{
return (DefTrackPoint*)cvGetSeqElem(m_pSeq,PointIndex);
};
inline void DelPoint(int PointIndex)
{
cvSeqRemove(m_pSeq,PointIndex);
};
inline void Clear()
{
cvClearSeq(m_pSeq);
};
inline void AddPoint(float x, float y, float r)
{
DefTrackPoint p = {x,y,r,0};
int Num = GetPointNum();
if(Num > 0)
{
DefTrackPoint* pPrev = GetPoint(Num-1);
float Alpha = 0.8f;
float dx = x-pPrev->x;
float dy = y-pPrev->y;
p.vx = Alpha*dx+(1-Alpha)*pPrev->vx;
p.vy = Alpha*dy+(1-Alpha)*pPrev->vy;
p.v = Alpha*dx+(1-Alpha)*pPrev->v;
}
AddPoint(&p);
}
inline void AddPoint(DefTrackPoint* pB)
{ /* Add point and recalculate last velocities: */
int wnd=3;
int Num;
int i;
cvSeqPush(m_pSeq,pB);
Num = GetPointNum();
for(i=MAX(0,Num-wnd-1); i<Num; ++i)
{ /* Next updating point: */
DefTrackPoint* p = GetPoint(i);
int j0 = i - wnd;
int j1 = i + wnd;
if(j0<0) j0 = 0;
if(j1>=Num)j1=Num-1;
if(j1>j0)
{
float dt = (float)(j1-j0);
DefTrackPoint* p0 = GetPoint(j0);
DefTrackPoint* p1 = GetPoint(j1);
p->vx = (p1->x - p0->x) / dt;
p->vy = (p1->y - p0->y) / dt;
p->v = (float)sqrt(p->vx*p->vx+p->vy*p->vy);
}
} /* Next updating point. */
#if 0
if(0)
{ /* Debug: */
int i;
printf("Blob %d: ",ID);
for(i=0; i<GetPointNum(); ++i)
{
DefTrackPoint* p = GetPoint(i);
printf(",(%.2f,%.2f,%f.2)",p->vx,p->vy,p->v);
}
printf("\n");
}
#endif
};
inline int GetPointNum()
{
return m_pSeq->total;
};
private:
CvMemStorage* m_pMem;
CvSeq* m_pSeq;
};
/* Fill array pIdxPairs by pair of index of correspondent blobs. */
/* Return number of pairs. */
/* pIdxPairs must have size not less that 2*(pSeqNum+pSeqTNum) */
/* pTmp is pointer to memory which size is pSeqNum*pSeqTNum*16 */
typedef struct DefMatch
{
int Idx; /* Previous best blob index. */
int IdxT; /* Previous best template blob index. */
double D; /* Blob to blob distance sum. */
} DefMatch;
static int cvTrackMatch(DefTrackRec* pSeq, int MaxLen, DefTrackRec* pSeqT, int* pIdxPairs, void* pTmp)
{
int NumPair = 0;
DefMatch* pMT = (DefMatch*)pTmp;
int Num = pSeq->GetPointNum();
int NumT = pSeqT->GetPointNum();
int i,it;
int i0=0; /* Last point in the track sequence. */
if(MaxLen > 0 && Num > MaxLen)
{ /* Set new point seq len and new last point in this seq: */
Num = MaxLen;
i0 = pSeq->GetPointNum() - Num;
}
for(i=0; i<Num; ++i)
{ /* For each point row: */
for(it=0; it<NumT; ++it)
{ /* For each point template column: */
DefTrackPoint* pB = pSeq->GetPoint(i+i0);
DefTrackPoint* pBT = pSeqT->GetPoint(it);
DefMatch* pMT_cur = pMT + i*NumT + it;
double dx = pB->x-pBT->x;
double dy = pB->y-pBT->y;
double D = dx*dx+dy*dy;
int DI[3][2] = {{-1,-1},{-1,0},{0,-1}};
int iDI;
pMT_cur->D = D;
pMT_cur->Idx = -1;
pMT_cur->IdxT = 0;
if(i==0) continue;
for(iDI=0; iDI<3; ++iDI)
{
int i_prev = i+DI[iDI][0];
int it_prev = it+DI[iDI][1];
if(i_prev >= 0 && it_prev>=0)
{
double D_cur = D+pMT[NumT*i_prev+it_prev].D;
if(pMT_cur->D > D_cur || (pMT_cur->Idx<0) )
{ /* Set new best local way: */
pMT_cur->D = D_cur;
pMT_cur->Idx = i_prev;
pMT_cur->IdxT = it_prev;
}
}
} /* Check next direction. */
} /* Fill next colum from table. */
} /* Fill next row. */
{ /* Back tracking. */
/* Find best end in template: */
int it_best = 0;
DefMatch* pMT_best = pMT + (Num-1)*NumT;
i = Num-1; /* set current i to last position */
for(it=1; it<NumT; ++it)
{
DefMatch* pMT_new = pMT + it + i*NumT;
if(pMT_best->D > pMT_new->D)
{
pMT_best->D = pMT_new->D;
it_best = it;
}
} /* Find best end template point. */
/* Back tracking whole sequence: */
for(it = it_best;i>=0 && it>=0;)
{
DefMatch* pMT_new = pMT + it + i*NumT;
pIdxPairs[2*NumPair] = i+i0;
pIdxPairs[2*NumPair+1] = it;
NumPair++;
it = pMT_new->IdxT;
i = pMT_new->Idx;
}
} /* End back tracing. */
return NumPair;
} /* cvTrackMatch. */
typedef struct DefTrackForDist
{
CvBlob blob;
DefTrackRec* pTrack;
int LastFrame;
float state;
/* for debug */
int close;
} DefTrackForDist;
class CvBlobTrackAnalysisTrackDist : public CvBlobTrackAnalysis
{
/*---------------- Internal functions: --------------------*/
private:
const char* m_pDebugAVIName; /* For debugging. */
//CvVideoWriter* m_pDebugAVI; /* For debugging. */
IplImage* m_pDebugImg; /* For debugging. */
char m_DataFileName[1024];
CvBlobSeq m_Tracks;
CvBlobSeq m_TrackDataBase;
int m_Frame;
void* m_pTempData;
int m_TempDataSize;
int m_TraceLen;
float m_AbnormalThreshold;
float m_PosThreshold;
float m_VelThreshold;
inline void* ReallocTempData(int Size)
{
if(Size <= m_TempDataSize && m_pTempData) return m_pTempData;
cvFree(&m_pTempData);
m_TempDataSize = 0;
m_pTempData = cvAlloc(Size);
if(m_pTempData) m_TempDataSize = Size;
return m_pTempData;
} /* ReallocTempData. */
public:
CvBlobTrackAnalysisTrackDist():m_Tracks(sizeof(DefTrackForDist)),m_TrackDataBase(sizeof(DefTrackForDist))
{
m_pDebugImg = 0;
//m_pDebugAVI = 0;
m_Frame = 0;
m_pTempData = NULL;
m_TempDataSize = 0;
m_pDebugAVIName = NULL;
AddParam("DebugAVI",&m_pDebugAVIName);
CommentParam("DebugAVI","Name of AVI file to save images from debug window");
m_TraceLen = 50;
AddParam("TraceLen",&m_TraceLen);
CommentParam("TraceLen","Length (in frames) of trajectory part that is used for comparison");
m_AbnormalThreshold = 0.02f;
AddParam("AbnormalThreshold",&m_AbnormalThreshold);
CommentParam("AbnormalThreshold","If trajectory is equal with less then <AbnormalThreshold*DataBaseTrackNum> tracks then trajectory is abnormal");
m_PosThreshold = 1.25;
AddParam("PosThreshold",&m_PosThreshold);
CommentParam("PosThreshold","Minimal allowd distance in blob width that is allowed");
m_VelThreshold = 0.5;
AddParam("VelThreshold",&m_VelThreshold);
CommentParam("VelThreshold","Minimal allowed relative difference between blob speed");
SetModuleName("TrackDist");
} /* Constructor. */
~CvBlobTrackAnalysisTrackDist()
{
int i;
for(i=m_Tracks.GetBlobNum(); i>0; --i)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
delete pF->pTrack;
}
if(m_pDebugImg) cvReleaseImage(&m_pDebugImg);
//if(m_pDebugAVI) cvReleaseVideoWriter(&m_pDebugAVI);
} /* Destructor. */
/*----------------- Interface: --------------------*/
virtual void AddBlob(CvBlob* pBlob)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* Create new TRack record: */
DefTrackForDist F;
F.state = 0;
F.blob = pBlob[0];
F.LastFrame = m_Frame;
F.pTrack = new DefTrackRec(CV_BLOB_ID(pBlob));
m_Tracks.AddBlob((CvBlob*)&F);
pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
assert(pF->pTrack);
pF->pTrack->AddPoint(pBlob->x,pBlob->y,pBlob->w*0.5f);
pF->blob = pBlob[0];
pF->LastFrame = m_Frame;
};
virtual void Process(IplImage* pImg, IplImage* /*pFG*/)
{
int i;
double MinTv = pImg->width/1440.0; /* minimal threshold for speed difference */
double MinTv2 = MinTv*MinTv;
for(i=m_Tracks.GetBlobNum(); i>0; --i)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
pF->state = 0;
if(pF->LastFrame == m_Frame || pF->LastFrame+1 == m_Frame)
{ /* Process one blob trajectory: */
int NumEq = 0;
int it;
for(it=m_TrackDataBase.GetBlobNum(); it>0; --it)
{ /* Check template: */
DefTrackForDist* pFT = (DefTrackForDist*)m_TrackDataBase.GetBlob(it-1);
int Num = pF->pTrack->GetPointNum();
int NumT = pFT->pTrack->GetPointNum();
int* pPairIdx = (int*)ReallocTempData(sizeof(int)*2*(Num+NumT)+sizeof(DefMatch)*Num*NumT);
void* pTmpData = pPairIdx+2*(Num+NumT);
int PairNum = 0;
int k;
int Equal = 1;
int UseVel = 0;
int UsePos = 0;
if(i==it) continue;
/* Match track: */
PairNum = cvTrackMatch( pF->pTrack, m_TraceLen, pFT->pTrack, pPairIdx, pTmpData );
Equal = MAX(1,cvRound(PairNum*0.1));
UseVel = 3*pF->pTrack->GetPointNum() > m_TraceLen;
UsePos = 10*pF->pTrack->GetPointNum() > m_TraceLen;
{ /* Check continues: */
float D;
int DI = pPairIdx[0*2+0]-pPairIdx[(PairNum-1)*2+0];
int DIt = pPairIdx[0*2+1]-pPairIdx[(PairNum-1)*2+1];
if(UseVel && DI != 0)
{
D = (float)(DI-DIt)/(float)DI;
if(fabs(D)>m_VelThreshold)Equal=0;
if(fabs(D)>m_VelThreshold*0.5)Equal/=2;
}
} /* Check continues. */
for(k=0; Equal>0 && k<PairNum; ++k)
{ /* Compare with threshold: */
int j = pPairIdx[k*2+0];
int jt = pPairIdx[k*2+1];
DefTrackPoint* pB = pF->pTrack->GetPoint(j);
DefTrackPoint* pBT = pFT->pTrack->GetPoint(jt);
double dx = pB->x-pBT->x;
double dy = pB->y-pBT->y;
double dvx = pB->vx - pBT->vx;
double dvy = pB->vy - pBT->vy;
//double dv = pB->v - pBT->v;
double D = dx*dx+dy*dy;
double Td = pBT->r*m_PosThreshold;
double dv2 = dvx*dvx+dvy*dvy;
double Tv2 = (pBT->vx*pBT->vx+pBT->vy*pBT->vy)*m_VelThreshold*m_VelThreshold;
double Tvm = pBT->v*m_VelThreshold;
if(Tv2 < MinTv2) Tv2 = MinTv2;
if(Tvm < MinTv) Tvm = MinTv;
/* Check trajectory position: */
if(UsePos && D > Td*Td)
{
Equal--;
}
else
/* Check trajectory velocity. */
/* Don't consider trajectory tail because its unstable for velocity computation. */
if(UseVel && j>5 && jt>5 && dv2 > Tv2 )
{
Equal--;
}
} /* Compare with threshold. */
if(Equal>0)
{
NumEq++;
pFT->close++;
}
} /* Next template. */
{ /* Calculate state: */
float T = m_TrackDataBase.GetBlobNum() * m_AbnormalThreshold; /* calc threshold */
if(T>0)
{
pF->state = (T - NumEq)/(T*0.2f) + 0.5f;
}
if(pF->state<0)pF->state=0;
if(pF->state>1)pF->state=1;
/*if(0)if(pF->state>0)
{// if abnormal blob
printf("Abnormal blob(%d) %d < %f, state=%f\n",CV_BLOB_ID(pF),NumEq,T, pF->state);
}*/
} /* Calculate state. */
} /* Process one blob trajectory. */
else
{ /* Move track to tracks data base: */
m_TrackDataBase.AddBlob((CvBlob*)pF);
m_Tracks.DelBlob(i-1);
}
} /* Next blob. */
if(m_Wnd)
{ /* Debug output: */
int i;
if(m_pDebugImg==NULL)
m_pDebugImg = cvCloneImage(pImg);
else
cvCopy(pImg, m_pDebugImg);
for(i=m_TrackDataBase.GetBlobNum(); i>0; --i)
{ /* Draw all elements in track data base: */
int j;
DefTrackForDist* pF = (DefTrackForDist*)m_TrackDataBase.GetBlob(i-1);
CvScalar color = CV_RGB(0,0,0);
if(!pF->close) continue;
if(pF->close)
{
color = CV_RGB(0,0,255);
}
else
{
color = CV_RGB(0,0,128);
}
for(j=pF->pTrack->GetPointNum(); j>0; j--)
{
DefTrackPoint* pB = pF->pTrack->GetPoint(j-1);
int r = 0;//MAX(cvRound(pB->r),1);
cvCircle(m_pDebugImg, cvPoint(cvRound(pB->x),cvRound(pB->y)), r, color);
}
pF->close = 0;
} /* Draw all elements in track data base. */
for(i=m_Tracks.GetBlobNum(); i>0; --i)
{ /* Draw all elements for all trajectories: */
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
int j;
int c = cvRound(pF->state*255);
CvScalar color = CV_RGB(c,255-c,0);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pF));
int x = cvRound(CV_BLOB_RX(pF)), y = cvRound(CV_BLOB_RY(pF));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( m_pDebugImg,
p,
s,
0, 0, 360,
CV_RGB(c,255-c,0), cvRound(1+(0*c)/255) );
for(j=pF->pTrack->GetPointNum(); j>0; j--)
{
DefTrackPoint* pB = pF->pTrack->GetPoint(j-1);
if(pF->pTrack->GetPointNum()-j > m_TraceLen) break;
cvCircle(m_pDebugImg, cvPoint(cvRound(pB->x),cvRound(pB->y)), 0, color);
}
pF->close = 0;
} /* Draw all elements for all trajectories. */
//cvNamedWindow("Tracks",0);
//cvShowImage("Tracks", m_pDebugImg);
} /* Debug output. */
#if 0
if(m_pDebugImg && m_pDebugAVIName)
{
if(m_pDebugAVI==NULL)
{ /* Create avi file for writing: */
m_pDebugAVI = cvCreateVideoWriter(
m_pDebugAVIName,
CV_FOURCC('x','v','i','d'),
25,
cvSize(m_pDebugImg->width,m_pDebugImg->height));
if(m_pDebugAVI == NULL)
{
printf("WARNING!!! Can not create AVI file %s for writing\n",m_pDebugAVIName);
}
} /* Create avi file for writing. */
if(m_pDebugAVI)cvWriteFrame( m_pDebugAVI, m_pDebugImg );
} /* Write debug window to AVI file. */
#endif
m_Frame++;
};
float GetState(int BlobID)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlobByID(BlobID);
return pF?pF->state:0.0f;
};
/* Return 0 if trajectory is normal;
return >0 if trajectory abnormal. */
virtual const char* GetStateDesc(int BlobID)
{
if(GetState(BlobID)>0.5) return "abnormal";
return NULL;
}
virtual void SetFileName(char* DataBaseName)
{
m_DataFileName[0] = 0;
if(DataBaseName)
{
strncpy(m_DataFileName,DataBaseName,1000);
strcat(m_DataFileName, ".yml");
}
};
virtual void Release(){ delete this; };
};
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisTrackDist()
{return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisTrackDist;}

View File

@@ -0,0 +1,185 @@
/*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*/
#include "precomp.hpp"
typedef struct DefBlobTrack
{
CvBlob blob;
CvBlobSeq* pSeq;
int FrameBegin;
int FrameLast;
int Saved; /* flag */
} DefBlobTrack;
static void SaveTrack(DefBlobTrack* pTrack, char* pFileName, int norm = 0)
{ /* Save blob track: */
int j;
FILE* out = NULL;
CvBlobSeq* pS = pTrack->pSeq;
CvBlob* pB0 = pS?pS->GetBlob(0):NULL;
if(pFileName == NULL) return;
if(pTrack == NULL) return;
out = fopen(pFileName,"at");
if(out == NULL)
{
printf("Warning! Cannot open %s file for track output\n", pFileName);
return;
}
fprintf(out,"%d",pTrack->FrameBegin);
if(pS) for(j=0; j<pS->GetBlobNum(); ++j)
{
CvBlob* pB = pS->GetBlob(j);
fprintf(out,", %.1f, %.1f", CV_BLOB_X(pB),CV_BLOB_Y(pB));
if(CV_BLOB_WX(pB0)>0)
fprintf(out,", %.2f",CV_BLOB_WX(pB)/(norm?CV_BLOB_WX(pB0):1));
if(CV_BLOB_WY(pB0)>0)
fprintf(out,", %.2f",CV_BLOB_WY(pB)/(norm?CV_BLOB_WY(pB0):1));
}
fprintf(out,"\n");
fclose(out);
pTrack->Saved = 1;
} /* Save blob track. */
class CvBlobTrackGen1:public CvBlobTrackGen
{
public:
CvBlobTrackGen1(int BlobSizeNorm = 0):m_TrackList(sizeof(DefBlobTrack))
{
m_BlobSizeNorm = BlobSizeNorm;
m_Frame = 0;
m_pFileName = NULL;
SetModuleName("Gen1");
};
~CvBlobTrackGen1()
{
int i;
for(i=m_TrackList.GetBlobNum();i>0;--i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(!pTrack->Saved)
{ /* Save track: */
SaveTrack(pTrack, m_pFileName, m_BlobSizeNorm);
} /* Save track. */
/* Delete sequence: */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
} /* Check next track. */
} /* Destructor. */
void SetFileName(char* pFileName){m_pFileName = pFileName;};
void AddBlob(CvBlob* pBlob)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pTrack==NULL)
{ /* Add new track: */
DefBlobTrack Track;
Track.blob = pBlob[0];
Track.FrameBegin = m_Frame;
Track.pSeq = new CvBlobSeq;
Track.Saved = 0;
m_TrackList.AddBlob((CvBlob*)&Track);
pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
} /* Add new track. */
assert(pTrack);
pTrack->FrameLast = m_Frame;
assert(pTrack->pSeq);
pTrack->pSeq->AddBlob(pBlob);
};
void Process(IplImage* /*pImg*/ = NULL, IplImage* /*pFG*/ = NULL)
{
int i;
for(i=m_TrackList.GetBlobNum(); i>0; --i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(pTrack->FrameLast < m_Frame && !pTrack->Saved)
{ /* Save track: */
SaveTrack(pTrack, m_pFileName, m_BlobSizeNorm);
if(pTrack->Saved)
{ /* delete sequence */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
m_TrackList.DelBlob(i-1);
}
} /* Save track. */
} /* Check next track. */
m_Frame++;
}
void Release()
{
delete this;
}
protected:
int m_Frame;
char* m_pFileName;
CvBlobSeq m_TrackList;
int m_BlobSizeNorm;
}; /* class CvBlobTrackGen1 */
CvBlobTrackGen* cvCreateModuleBlobTrackGen1()
{
return (CvBlobTrackGen*) new CvBlobTrackGen1(0);
}

View File

@@ -0,0 +1,219 @@
/*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
//
// 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*/
#include "precomp.hpp"
typedef struct DefBlobTrack
{
CvBlob blob;
CvBlobSeq* pSeq;
int FrameBegin;
int FrameLast;
int Saved; /* flag */
} DefBlobTrack;
class CvBlobTrackGenYML:public CvBlobTrackGen
{
protected:
int m_Frame;
char* m_pFileName;
CvBlobSeq m_TrackList;
CvSize m_Size;
void SaveAll()
{
int ObjNum = m_TrackList.GetBlobNum();
int i;
char video_name[1024];
char* struct_name = NULL;
CvFileStorage* storage = cvOpenFileStorage(m_pFileName,NULL,CV_STORAGE_WRITE_TEXT);
if(storage==NULL)
{
printf("WARNING!!! Cannot open %s file for trajectory output.", m_pFileName);
}
for(i=0; i<1024 && m_pFileName[i]!='.' && m_pFileName[i]!=0; ++i) video_name[i]=m_pFileName[i];
video_name[i] = 0;
for(;i>0; i--)
{
if(video_name[i-1] == '\\') break;
if(video_name[i-1] == '/') break;
if(video_name[i-1] == ':') break;
}
struct_name = video_name + i;
cvStartWriteStruct(storage, struct_name, CV_NODE_SEQ);
for(i=0; i<ObjNum; ++i)
{
char obj_name[1024];
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i);
if(pTrack==NULL) continue;
sprintf(obj_name,"%s_obj%d",struct_name,i);
cvStartWriteStruct(storage, NULL, CV_NODE_MAP);
cvWriteInt(storage, "FrameBegin", pTrack->FrameBegin);
cvWriteString(storage, "VideoObj", obj_name);
cvEndWriteStruct( storage );
pTrack->Saved = 1;
}
cvEndWriteStruct( storage );
for(i=0;i<ObjNum;++i)
{
char obj_name[1024];
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i);
CvBlobSeq* pSeq = pTrack->pSeq;
sprintf(obj_name,"%s_obj%d",struct_name,i);
cvStartWriteStruct(storage, obj_name, CV_NODE_MAP);
{ /* Write position: */
int j;
CvPoint2D32f p;
cvStartWriteStruct(storage, "Pos", CV_NODE_SEQ|CV_NODE_FLOW);
for(j=0;j<pSeq->GetBlobNum();++j)
{
CvBlob* pB = pSeq->GetBlob(j);
p.x = pB->x/(m_Size.width-1);
p.y = pB->y/(m_Size.height-1);
cvWriteRawData(storage, &p, 1 ,"ff");
}
cvEndWriteStruct( storage );
}
{ /* Write size: */
int j;
CvPoint2D32f p;
cvStartWriteStruct(storage, "Size", CV_NODE_SEQ|CV_NODE_FLOW);
for(j=0; j<pSeq->GetBlobNum(); ++j)
{
CvBlob* pB = pSeq->GetBlob(j);
p.x = pB->w/(m_Size.width-1);
p.y = pB->h/(m_Size.height-1);
cvWriteRawData(storage, &p, 1 ,"ff");
}
cvEndWriteStruct( storage );
}
cvEndWriteStruct( storage );
}
cvReleaseFileStorage(&storage);
} /* Save All */
public:
CvBlobTrackGenYML():m_TrackList(sizeof(DefBlobTrack))
{
m_Frame = 0;
m_pFileName = NULL;
m_Size = cvSize(2,2);
SetModuleName("YML");
};
~CvBlobTrackGenYML()
{
int i;
SaveAll();
for(i=m_TrackList.GetBlobNum(); i>0; --i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
/* Delete sequence: */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
} /* Check next track. */
} /* Destructor. */
void SetFileName(char* pFileName){m_pFileName = pFileName;};
void AddBlob(CvBlob* pBlob)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pTrack==NULL)
{ /* Add new track: */
DefBlobTrack Track;
Track.blob = pBlob[0];
Track.FrameBegin = m_Frame;
Track.pSeq = new CvBlobSeq;
Track.Saved = 0;
m_TrackList.AddBlob((CvBlob*)&Track);
pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
} /* Add new track. */
assert(pTrack);
pTrack->FrameLast = m_Frame;
assert(pTrack->pSeq);
pTrack->pSeq->AddBlob(pBlob);
};
void Process(IplImage* pImg = NULL, IplImage* /*pFG*/ = NULL)
{
int i;
m_Size = cvSize(pImg->width,pImg->height);
for(i=m_TrackList.GetBlobNum(); i>0; --i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(pTrack->FrameLast < m_Frame && !pTrack->Saved)
{ /* Save track: */
SaveAll();
} /* Save track. */
} /* Check next track. */
m_Frame++;
}
void Release()
{
delete this;
}
}; /* class CvBlobTrackGenYML */
CvBlobTrackGen* cvCreateModuleBlobTrackGenYML()
{
return (CvBlobTrackGen*) new CvBlobTrackGenYML;
}

View File

@@ -0,0 +1,485 @@
/*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
//
// Copyright (C) 2000, Intel Corporation, 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*/
/*
This file contain simple implementation of BlobTrackerAuto virtual interface
This module just connected other low level 3 modules
(foreground estimator + BlobDetector + BlobTracker)
and some simple code to detect "lost tracking"
The track is lost when integral of foreground mask image by blob area has low value
*/
#include "precomp.hpp"
#include <time.h>
/* list of Blob Detection modules */
CvBlobDetector* cvCreateBlobDetectorSimple();
/* Get frequency for each module time working estimation: */
static double FREQ = 1000*cvGetTickFrequency();
#if 1
#define COUNTNUM 100
#define TIME_BEGIN() \
{\
static double _TimeSum = 0;\
static int _Count = 0;\
static int _CountBlob = 0;\
int64 _TickCount = cvGetTickCount();\
#define TIME_END(_name_,_BlobNum_) \
_Count++;\
_CountBlob+=_BlobNum_;\
_TimeSum += (cvGetTickCount()-_TickCount)/FREQ;\
if(m_TimesFile)if(_Count%COUNTNUM==0)\
{ \
FILE* out = fopen(m_TimesFile,"at");\
if(out)\
{\
fprintf(out,"ForFrame Frame: %d %s %f on %f blobs\n",_Count,_name_, _TimeSum/COUNTNUM,((float)_CountBlob)/COUNTNUM);\
if(_CountBlob>0)fprintf(out,"ForBlob Frame: %d %s - %f\n",_Count,_name_, _TimeSum/_CountBlob);\
fclose(out);\
}\
_TimeSum = 0;\
_CountBlob = 0;\
}\
}
#else
#define TIME_BEGIN()
#define TIME_END(_name_)
#endif
/* Special extended blob structure for auto blob tracking: */
typedef struct CvBlobTrackAuto
{
CvBlob blob;
int BadFrames;
} CvBlobTrackAuto;
class CvBlobTrackerAuto1: public CvBlobTrackerAuto
{
public:
CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param);
~CvBlobTrackerAuto1();
CvBlob* GetBlob(int index){return m_BlobList.GetBlob(index);};
CvBlob* GetBlobByID(int ID){return m_BlobList.GetBlobByID(ID);};
int GetBlobNum(){return m_BlobList.GetBlobNum();};
virtual IplImage* GetFGMask(){return m_pFGMask;};
float GetState(int BlobID){return m_pBTA?m_pBTA->GetState(BlobID):0;};
const char* GetStateDesc(int BlobID){return m_pBTA?m_pBTA->GetStateDesc(BlobID):NULL;};
/* Return 0 if trajectory is normal;
return >0 if trajectory abnormal. */
void Process(IplImage* pImg, IplImage* pMask = NULL);
void Release(){delete this;};
private:
IplImage* m_pFGMask;
int m_FGTrainFrames;
CvFGDetector* m_pFG; /* Pointer to foreground mask detector module. */
CvBlobTracker* m_pBT; /* Pointer to Blob tracker module. */
int m_BTDel;
int m_BTReal;
CvBlobDetector* m_pBD; /* Pointer to Blob detector module. */
int m_BDDel;
CvBlobTrackGen* m_pBTGen;
CvBlobTrackPostProc* m_pBTPostProc;
int m_UsePPData;
CvBlobTrackAnalysis* m_pBTA; /* Blob trajectory analyser. */
CvBlobSeq m_BlobList;
int m_FrameCount;
int m_NextBlobID;
const char* m_TimesFile;
public:
virtual void SaveState(CvFileStorage* fs)
{
cvWriteInt(fs,"FrameCount",m_FrameCount);
cvWriteInt(fs,"NextBlobID",m_NextBlobID);
m_BlobList.Write(fs,"BlobList");
};
virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
{
CvFileNode* BlobListNode = cvGetFileNodeByName(fs,node,"BlobList");
m_FrameCount = cvReadIntByName(fs,node, "FrameCount", m_FrameCount);
m_NextBlobID = cvReadIntByName(fs,node, "NextBlobID", m_NextBlobID);
if(BlobListNode)
{
m_BlobList.Load(fs,BlobListNode);
}
};
};
/* Auto Blob tracker creater (sole interface function for this file) */
CvBlobTrackerAuto* cvCreateBlobTrackerAuto1(CvBlobTrackerAutoParam1* param)
{
return (CvBlobTrackerAuto*)new CvBlobTrackerAuto1(param);
}
/* Constructor of auto blob tracker: */
CvBlobTrackerAuto1::CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param):m_BlobList(sizeof(CvBlobTrackAuto))
{
m_BlobList.AddFormat("i");
m_TimesFile = NULL;
AddParam("TimesFile",&m_TimesFile);
m_NextBlobID = 0;
m_pFGMask = NULL;
m_FrameCount = 0;
m_FGTrainFrames = param?param->FGTrainFrames:0;
m_pFG = param?param->pFG:0;
m_BDDel = 0;
m_pBD = param?param->pBD:NULL;
m_BTDel = 0;
m_pBT = param?param->pBT:NULL;;
m_BTReal = m_pBT?m_pBT->IsModuleName("BlobTrackerReal"):0;
m_pBTGen = param?param->pBTGen:NULL;
m_pBTA = param?param->pBTA:NULL;
m_pBTPostProc = param?param->pBTPP:NULL;
m_UsePPData = param?param->UsePPData:0;
/* Create default submodules: */
if(m_pBD==NULL)
{
m_pBD = cvCreateBlobDetectorSimple();
m_BDDel = 1;
}
if(m_pBT==NULL)
{
m_pBT = cvCreateBlobTrackerMS();
m_BTDel = 1;
}
SetModuleName("Auto1");
} /* CvBlobTrackerAuto1::CvBlobTrackerAuto1 */
/* Destructor for auto blob tracker: */
CvBlobTrackerAuto1::~CvBlobTrackerAuto1()
{
if(m_BDDel)m_pBD->Release();
if(m_BTDel)m_pBT->Release();
}
void CvBlobTrackerAuto1::Process(IplImage* pImg, IplImage* pMask)
{
int CurBlobNum = 0;
int i;
IplImage* pFG = pMask;
/* Bump frame counter: */
m_FrameCount++;
if(m_TimesFile)
{
static int64 TickCount = cvGetTickCount();
static double TimeSum = 0;
static int Count = 0;
Count++;
if(Count%100==0)
{
#ifndef WINCE
time_t ltime;
time( &ltime );
char* stime = ctime( &ltime );
#else
/* WINCE does not have above POSIX functions (time,ctime) */
const char* stime = " wince ";
#endif
FILE* out = fopen(m_TimesFile,"at");
double Time;
TickCount = cvGetTickCount()-TickCount;
Time = TickCount/FREQ;
if(out){fprintf(out,"- %sFrame: %d ALL_TIME - %f\n",stime,Count,Time/1000);fclose(out);}
TimeSum = 0;
TickCount = cvGetTickCount();
}
}
/* Update BG model: */
TIME_BEGIN()
if(m_pFG)
{ /* If FG detector is needed: */
m_pFG->Process(pImg);
pFG = m_pFG->GetMask();
} /* If FG detector is needed. */
TIME_END("FGDetector",-1)
m_pFGMask = pFG; /* For external use. */
/*if(m_pFG && m_pFG->GetParam("DebugWnd") == 1)
{// debug foreground result
IplImage *pFG = m_pFG->GetMask();
if(pFG)
{
cvNamedWindow("FG",0);
cvShowImage("FG", pFG);
}
}*/
/* Track blobs: */
TIME_BEGIN()
if(m_pBT)
{
int i;
m_pBT->Process(pImg, pFG);
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Update data of tracked blob list: */
CvBlob* pB = m_BlobList.GetBlob(i-1);
int BlobID = CV_BLOB_ID(pB);
int i = m_pBT->GetBlobIndexByID(BlobID);
m_pBT->ProcessBlob(i, pB, pImg, pFG);
pB->ID = BlobID;
}
CurBlobNum = m_pBT->GetBlobNum();
}
TIME_END("BlobTracker",CurBlobNum)
/* This part should be removed: */
if(m_BTReal && m_pBT)
{ /* Update blob list (detect new blob for real blob tracker): */
int i;
for(i=m_pBT->GetBlobNum(); i>0; --i)
{ /* Update data of tracked blob list: */
CvBlob* pB = m_pBT->GetBlob(i-1);
if(pB && m_BlobList.GetBlobByID(CV_BLOB_ID(pB)) == NULL )
{
CvBlobTrackAuto NewB;
NewB.blob = pB[0];
NewB.BadFrames = 0;
m_BlobList.AddBlob((CvBlob*)&NewB);
}
} /* Next blob. */
/* Delete blobs: */
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Update tracked-blob list: */
CvBlob* pB = m_BlobList.GetBlob(i-1);
if(pB && m_pBT->GetBlobByID(CV_BLOB_ID(pB)) == NULL )
{
m_BlobList.DelBlob(i-1);
}
} /* Next blob. */
} /* Update bloblist. */
TIME_BEGIN()
if(m_pBTPostProc)
{ /* Post-processing module: */
int i;
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Update tracked-blob list: */
CvBlob* pB = m_BlobList.GetBlob(i-1);
m_pBTPostProc->AddBlob(pB);
}
m_pBTPostProc->Process();
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Update tracked-blob list: */
CvBlob* pB = m_BlobList.GetBlob(i-1);
int BlobID = CV_BLOB_ID(pB);
CvBlob* pBN = m_pBTPostProc->GetBlobByID(BlobID);
if(pBN && m_UsePPData && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
{ /* Set new data for tracker: */
m_pBT->SetBlobByID(BlobID, pBN );
}
if(pBN)
{ /* Update blob list with results from postprocessing: */
pB[0] = pBN[0];
}
}
} /* Post-processing module. */
TIME_END("PostProcessing",CurBlobNum)
/* Blob deleter (experimental and simple): */
TIME_BEGIN()
if(pFG)
{ /* Blob deleter: */
int i;
if(!m_BTReal)for(i=m_BlobList.GetBlobNum();i>0;--i)
{ /* Check all blobs on list: */
CvBlobTrackAuto* pB = (CvBlobTrackAuto*)(m_BlobList.GetBlob(i-1));
int Good = 0;
int w=pFG->width;
int h=pFG->height;
CvRect r = CV_BLOB_RECT(pB);
CvMat mat;
double aver = 0;
double area = CV_BLOB_WX(pB)*CV_BLOB_WY(pB);
if(r.x < 0){r.width += r.x;r.x = 0;}
if(r.y < 0){r.height += r.y;r.y = 0;}
if(r.x+r.width>=w){r.width = w-r.x-1;}
if(r.y+r.height>=h){r.height = h-r.y-1;}
if(r.width > 4 && r.height > 4 && r.x < w && r.y < h &&
r.x >=0 && r.y >=0 &&
r.x+r.width < w && r.y+r.height < h && area > 0)
{
aver = cvSum(cvGetSubRect(pFG,&mat,r)).val[0] / area;
/* if mask in blob area exists then its blob OK*/
if(aver > 0.1*255)Good = 1;
}
else
{
pB->BadFrames+=2;
}
if(Good)
{
pB->BadFrames = 0;
}
else
{
pB->BadFrames++;
}
} /* Next blob: */
/* Check error count: */
for(i=0; i<m_BlobList.GetBlobNum(); ++i)
{
CvBlobTrackAuto* pB = (CvBlobTrackAuto*)m_BlobList.GetBlob(i);
if(pB->BadFrames>3)
{ /* Delete such objects */
/* from tracker... */
m_pBT->DelBlobByID(CV_BLOB_ID(pB));
/* ... and from local list: */
m_BlobList.DelBlob(i);
i--;
}
} /* Check error count for next blob. */
} /* Blob deleter. */
TIME_END("BlobDeleter",m_BlobList.GetBlobNum())
/* Update blobs: */
TIME_BEGIN()
if(m_pBT)
m_pBT->Update(pImg, pFG);
TIME_END("BlobTrackerUpdate",CurBlobNum)
/* Detect new blob: */
TIME_BEGIN()
if(!m_BTReal && m_pBD && pFG && (m_FrameCount > m_FGTrainFrames) )
{ /* Detect new blob: */
static CvBlobSeq NewBlobList;
CvBlobTrackAuto NewB;
NewBlobList.Clear();
if(m_pBD->DetectNewBlob(pImg, pFG, &NewBlobList, &m_BlobList))
{ /* Add new blob to tracker and blob list: */
int i;
IplImage* pMask = pFG;
/*if(0)if(NewBlobList.GetBlobNum()>0 && pFG )
{// erode FG mask (only for FG_0 and MS1||MS2)
pMask = cvCloneImage(pFG);
cvErode(pFG,pMask,NULL,2);
}*/
for(i=0; i<NewBlobList.GetBlobNum(); ++i)
{
CvBlob* pBN = NewBlobList.GetBlob(i);
pBN->ID = m_NextBlobID;
if(pBN && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
{
CvBlob* pB = m_pBT->AddBlob(pBN, pImg, pMask );
if(pB)
{
NewB.blob = pB[0];
NewB.BadFrames = 0;
m_BlobList.AddBlob((CvBlob*)&NewB);
m_NextBlobID++;
}
}
} /* Add next blob from list of detected blob. */
if(pMask != pFG) cvReleaseImage(&pMask);
} /* Create and add new blobs and trackers. */
} /* Detect new blob. */
TIME_END("BlobDetector",-1)
TIME_BEGIN()
if(m_pBTGen)
{ /* Run track generator: */
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Update data of tracked blob list: */
CvBlob* pB = m_BlobList.GetBlob(i-1);
m_pBTGen->AddBlob(pB);
}
m_pBTGen->Process(pImg, pFG);
} /* Run track generator: */
TIME_END("TrajectoryGeneration",-1)
TIME_BEGIN()
if(m_pBTA)
{ /* Trajectory analysis module: */
int i;
for(i=m_BlobList.GetBlobNum(); i>0; i--)
m_pBTA->AddBlob(m_BlobList.GetBlob(i-1));
m_pBTA->Process(pImg, pFG);
} /* Trajectory analysis module. */
TIME_END("TrackAnalysis",m_BlobList.GetBlobNum())
} /* CvBlobTrackerAuto1::Process */

View File

@@ -0,0 +1,556 @@
/*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
//
// 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*/
#include "precomp.hpp"
static float CalcAverageMask(CvBlob* pBlob, IplImage* pImgFG )
{ /* Calculate sum of mask: */
double Area, Aver = 0;
CvRect r;
CvMat mat;
if(pImgFG==NULL) return 0;
r.x = cvRound(pBlob->x - pBlob->w*0.5);
r.y = cvRound(pBlob->y - pBlob->h*0.5);
r.width = cvRound(pBlob->w);
r.height = cvRound(pBlob->h);
Area = r.width*r.height;
if(r.x<0){r.width += r.x;r.x = 0;}
if(r.y<0){r.height += r.y;r.y = 0;}
if((r.x+r.width)>=pImgFG->width){r.width=pImgFG->width-r.x-1;}
if((r.y+r.height)>=pImgFG->height){r.height=pImgFG->height-r.y-1;}
if(r.width>0 && r.height>0)
{
double Sum = cvSum(cvGetSubRect(pImgFG,&mat,r)).val[0]/255.0;
assert(Area>0);
Aver = Sum/Area;
}
return (float)Aver;
} /* Calculate sum of mask. */
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */
typedef struct DefBlobTracker
{
CvBlob blob;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
int Collision;
CvBlobSeq* pBlobHyp;
float AverFG;
} DefBlobTracker;
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage);
class CvBlobTrackerCC : public CvBlobTracker
{
private:
float m_AlphaSize;
float m_AlphaPos;
float m_Alpha;
int m_Collision;
int m_ConfidenceType;
const char* m_ConfidenceTypeStr;
CvBlobSeq m_BlobList;
CvBlobSeq m_BlobListNew;
// int m_LastID;
CvMemStorage* m_pMem;
int m_ClearHyp;
IplImage* m_pImg;
IplImage* m_pImgFG;
public:
CvBlobTrackerCC():m_BlobList(sizeof(DefBlobTracker))
{
// m_LastID = 0;
m_ClearHyp = 0;
m_pMem = cvCreateMemStorage();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
AddParam("Collision",&m_Collision);
CommentParam("Collision", "If 1 then collision cases are processed in special way");
m_AlphaSize = 0.02f;
AddParam("AlphaSize",&m_AlphaSize);
CommentParam("AlphaSize", "Size update speed (0..1)");
m_AlphaPos = 1.0f;
AddParam("AlphaPos",&m_AlphaPos);
CommentParam("AlphaPos", "Position update speed (0..1)");
m_Alpha = 0.001f;
AddParam("Alpha", &m_Alpha);
CommentParam("Alpha","Coefficient for model histogram updating (0 - hist is not updated)");
m_ConfidenceType=0;
m_ConfidenceTypeStr = "NearestBlob";
AddParam("ConfidenceType", &m_ConfidenceTypeStr);
CommentParam("ConfidenceType","Type of calculated Confidence (NearestBlob, AverFG, BC)");
SetModuleName("CC");
};
~CvBlobTrackerCC()
{
if(m_pMem)cvReleaseMemStorage(&m_pMem);
};
/* Blob functions: */
virtual int GetBlobNum() {return m_BlobList.GetBlobNum();};
virtual CvBlob* GetBlob(int BlobIndex){return m_BlobList.GetBlob(BlobIndex);};
virtual void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
if(pB) pB[0] = pBlob[0];
};
virtual CvBlob* GetBlobByID(int BlobID){return m_BlobList.GetBlobByID(BlobID);};
virtual void DelBlob(int BlobIndex)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
if(pBT==NULL) return;
if(pBT->pPredictor)
{
pBT->pPredictor->Release();
}
else
{
printf("WARNING!!! Invalid Predictor in CC tracker");
}
delete pBT->pBlobHyp;
m_BlobList.DelBlob(BlobIndex);
};
#if 0
virtual void DelBlobByID(int BlobID)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlobByID(BlobID);
pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlobByID(BlobID);
};
#endif
virtual void Release(){delete this;};
/* Add new blob to track it and assign to this blob personal ID */
/* pBlob - pinter 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* pB, IplImage* /*pImg*/, IplImage* pImgFG = NULL )
{
assert(pImgFG); /* This tracker uses only foreground mask. */
DefBlobTracker NewB;
NewB.blob = pB[0];
// CV_BLOB_ID(&NewB) = m_LastID;
NewB.pBlobHyp = new CvBlobSeq;
NewB.pPredictor = cvCreateModuleBlobTrackPredictKalman(); /* Module for position prediction. */
NewB.pPredictor->Update(pB);
NewB.AverFG = pImgFG?CalcAverageMask(pB,pImgFG):0;
m_BlobList.AddBlob((CvBlob*)&NewB);
return m_BlobList.GetBlob(m_BlobList.GetBlobNum()-1);
};
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
CvSeq* cnts;
CvSeq* cnt;
int i;
m_pImg = pImg;
m_pImgFG = pImgFG;
if(m_BlobList.GetBlobNum() <= 0 ) return;
/* Clear bloblist for new blobs: */
m_BlobListNew.Clear();
assert(m_pMem);
cvClearMemStorage(m_pMem);
assert(pImgFG);
/* Find CC: */
#if 0
{ // By contour clustering:
cvFindBlobsByCCClasters(pImgFG, &m_BlobListNew, m_pMem);
}
#else
{ /* One contour - one blob: */
IplImage* pBin = cvCloneImage(pImgFG);
assert(pBin);
cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* Process each contour: */
for(cnt = cnts; cnt; cnt=cnt->h_next)
{
CvBlob NewBlob;
/* Image moments: */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < 3 || r.width < 3) continue;
cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
m_BlobListNew.AddBlob(&NewBlob);
} /* Next contour. */
cvReleaseImage(&pBin);
}
#endif
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Predict new blob position: */
CvBlob* pB=NULL;
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(i-1);
/* Update predictor by previous value of blob: */
pBT->pPredictor->Update(&(pBT->blob));
/* Predict current position: */
pB = pBT->pPredictor->Predict();
if(pB)
{
pBT->BlobPredict = pB[0];
}
else
{
pBT->BlobPredict = pBT->blob;
}
} /* Predict new blob position. */
if(m_Collision)
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Predict collision. */
int Collision = 0;
int j;
DefBlobTracker* pF = (DefBlobTracker*)m_BlobList.GetBlob(i-1);
for(j=m_BlobList.GetBlobNum(); j>0; --j)
{ /* Predict collision: */
CvBlob* pB1;
CvBlob* pB2;
DefBlobTracker* pF2 = (DefBlobTracker*)m_BlobList.GetBlob(j-1);
if(i==j) continue;
pB1 = &pF->BlobPredict;
pB2 = &pF2->BlobPredict;
if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;
pB1 = &pF->blob;
pB2 = &pF2->blob;
if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;
if(Collision) break;
} /* Check next blob to cross current. */
pF->Collision = Collision;
} /* Predict collision. */
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Find a neighbour on current frame
* for each blob from previous frame:
*/
CvBlob* pB = m_BlobList.GetBlob(i-1);
DefBlobTracker* pBT = (DefBlobTracker*)pB;
//int BlobID = CV_BLOB_ID(pB);
//CvBlob* pBBest = NULL;
//double DistBest = -1;
//int j;
if(pBT->pBlobHyp->GetBlobNum()>0)
{ /* Track all hypotheses: */
int h,hN = pBT->pBlobHyp->GetBlobNum();
for(h=0; h<hN; ++h)
{
int j, jN = m_BlobListNew.GetBlobNum();
CvBlob* pB = pBT->pBlobHyp->GetBlob(h);
int BlobID = CV_BLOB_ID(pB);
CvBlob* pBBest = NULL;
double DistBest = -1;
for(j=0; j<jN; j++)
{ /* Find best CC: */
double Dist = -1;
CvBlob* pBNew = m_BlobListNew.GetBlob(j);
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
if(dx > 2*CV_BLOB_WX(pB) || dy > 2*CV_BLOB_WY(pB)) continue;
Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
} /* Find best CC. */
if(pBBest)
{
pB[0] = pBBest[0];
CV_BLOB_ID(pB) = BlobID;
}
else
{ /* Delete this hypothesis. */
pBT->pBlobHyp->DelBlob(h);
h--;
hN--;
}
} /* Next hypothysis. */
} /* Track all hypotheses. */
} /* Track next blob. */
m_ClearHyp = 1;
} /* Process. */
virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
int ID = pBlob->ID;
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
DefBlobTracker* pBT = (DefBlobTracker*)pB;
//CvBlob* pBBest = NULL;
//double DistBest = -1;
int BlobID;
if(pB==NULL) return;
BlobID = pB->ID;
if(m_Collision && pBT->Collision)
{ /* Tracking in collision: */
pB[0]=pBT->BlobPredict;
CV_BLOB_ID(pB)=BlobID;
} /* Tracking in collision. */
else
{ /* Non-collision tracking: */
CvBlob* pBBest = GetNearestBlob(pB);
if(pBBest)
{
float w = pBlob->w*(1-m_AlphaSize)+m_AlphaSize*pBBest->w;
float h = pBlob->h*(1-m_AlphaSize)+m_AlphaSize*pBBest->h;
float x = pBlob->x*(1-m_AlphaPos)+m_AlphaPos*pBBest->x;
float y = pBlob->y*(1-m_AlphaPos)+m_AlphaPos*pBBest->y;
pB->w = w;
pB->h = h;
pB->x = x;
pB->y = y;
CV_BLOB_ID(pB) = BlobID;
}
} /* Non-collision tracking. */
pBlob[0] = pB[0];
pBlob->ID = ID;
};
virtual double GetConfidence(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* pImgFG = NULL)
{
/* Define coefficients in exp by exp(-XT*K)=VT: */
static double _KS = -log(0.1)/pow(0.5,2); /* XT = 1, VT = 0.1 - when size is Larger in 2 times Confidence is smoller in 10 times */
static double _KP = -log(0.1)/pow(m_pImg->width*0.02,2); /* XT = 0.02*ImgWidth, VT = 0.1*/
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
float dx,dy,dw,dh;
float dp2,ds2;
double W = 1;
CvBlob* pBC = GetNearestBlob(pBlob);
if(pBC == NULL ) return 0;
dx = pBC->x-pBlob->x;
dy = pBC->y-pBlob->y;
dw = (pBC->w-pBlob->w)/pBC->w;
dh = (pBC->h-pBlob->h)/pBC->h;
dp2 = dx*dx+dy*dy;
ds2 = dw*dw+dh*dh;
if(!pBT->Collision)
{ /* Confidence for size by nearest blob: */
W*=exp(-_KS*ds2);
}
if(m_ConfidenceType==0 && !pBT->Collision)
{ /* Confidence by nearest blob: */
W*=exp(-_KP*dp2);
}
if(m_ConfidenceType==1 && pBT->AverFG>0)
{ /* Calculate sum of mask: */
float Aver = CalcAverageMask(pBlob, pImgFG );
if(Aver < pBT->AverFG)
{
float diff = 1+0.9f*(Aver-pBT->AverFG)/pBT->AverFG;
if(diff < 0.1f) diff = 0.1f;
W *= diff;
}
} /* Calculate sum of mask. */
if(m_ConfidenceType==2)
{ /* Calculate BCoeff: */
float S = 0.2f;
float Aver = CalcAverageMask(pBlob, pImgFG );
double B = sqrt(Aver*pBT->AverFG)+sqrt((1-Aver)*(1-pBT->AverFG));
W *= exp((B-1)/(2*S));
} /* Calculate sum of mask. */
return W;
};
virtual void UpdateBlob(int BlobIndex, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* pImgFG = NULL)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
if(pImgFG==NULL || pBT==NULL) return;
if(!pBT->Collision)
{
//pBT->AverFG = pBT->AverFG * (1-m_Alpha) + m_Alpha * CalcAverageMask(pBlob,pImgFG);
}
};
virtual void ParamUpdate()
{
const char* pCT[3] = {"NearestBlob","AverFG","BC"};
int i;
CvBlobTracker::ParamUpdate();
for(i=0; i<3; ++i)
{
if(cv_stricmp(m_ConfidenceTypeStr,pCT[i])==0)
{
m_ConfidenceType = i;
}
}
SetParamStr("ConfidenceType",pCT[m_ConfidenceType]);
}
/* =============== MULTI HYPOTHESIS INTERFACE ================== */
/* Return number of position hypotheses of currently tracked blob: */
virtual int GetBlobHypNum(int BlobIdx)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIdx);
assert(pBT->pBlobHyp);
return pBT->pBlobHyp->GetBlobNum();
}; /* CvBlobtrackerList::GetBlobHypNum() */
/* Return pointer to specified blob hypothesis by index blob: */
virtual CvBlob* GetBlobHyp(int BlobIndex, int hypothesis)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
assert(pBT->pBlobHyp);
return pBT->pBlobHyp->GetBlob(hypothesis);
}; /* CvBlobtrackerList::GetBlobHyp() */
/* Set new parameters for specified (by index) blob hypothesis
* (can be called several times for each hypothesis):
*/
virtual void SetBlobHyp(int BlobIndex, CvBlob* pBlob)
{
if(m_ClearHyp)
{ /* Clear all hypotheses: */
int b, bN = m_BlobList.GetBlobNum();
for(b=0; b<bN; ++b)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(b);
assert(pBT->pBlobHyp);
pBT->pBlobHyp->Clear();
}
m_ClearHyp = 0;
}
{ /* Add hypothesis: */
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
assert(pBT->pBlobHyp);
pBT->pBlobHyp->AddBlob(pBlob);
}
};
private:
CvBlob* GetNearestBlob(CvBlob* pB)
{
//DefBlobTracker* pBT = (DefBlobTracker*)pB;
CvBlob* pBBest = NULL;
double DistBest = -1;
int j,BlobID;
if(pB==NULL) return NULL;
BlobID = pB->ID;
for(j=m_BlobListNew.GetBlobNum(); j>0; --j)
{ /* Find best CC: */
double Dist = -1;
CvBlob* pBNew = m_BlobListNew.GetBlob(j-1);
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
if(dx > 2*CV_BLOB_WX(pB) || dy > 2*CV_BLOB_WY(pB)) continue;
Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
} /* Find best CC. */
return pBBest;
}; /* GetNearestBlob */
};
CvBlobTracker* cvCreateBlobTrackerCC()
{
return (CvBlobTracker*) new CvBlobTrackerCC;
}
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */

View File

@@ -0,0 +1,495 @@
/*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
//
// 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*/
#include "precomp.hpp"
/* Blob (foreground-pixel connected-component) tracking with collision resolution.
*
* For entrypoints into the literature see:
*
* A Tutorial on Particle Filters for Online Nonlinear/Non-Gaussian Bayesian Tracking
* Arulampalam &t al, 2001, 15p
* http://www-clmc.usc.edu/publications/A/arulampalam-TSP2002.pdf
*
* Particle Filters for Positioning, Navigation, and Tracking
* Gustafsson et al, 2002 12p
* http://www.control.isy.liu.se/~fredrik/reports/01SPpf4pos.pdf
*
* Particle Filtering in High Clutter Environments
* Korhonen et al, 2005 4p
* http://www.cs.uku.fi/finsig05/papers/paper26_FINSIG05.pdf
*
* Appearance Models for Occlusion Handling
* Andrew Senior &t al, 8p 2001
* http://www.research.ibm.com/peoplevision/PETS2001.pdf
*
*/
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */
typedef struct DefBlobTrackerCR
{
CvBlob blob;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
CvBlob BlobPrev;
int Collision;
CvBlobSeq* pBlobHyp;
CvBlobTrackerOne* pResolver;
} DefBlobTrackerCR;
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage);
class CvBlobTrackerCCCR : public CvBlobTracker
{
private:
float m_AlphaSize;
int m_Collision;
CvBlobSeq m_BlobList;
CvBlobSeq m_BlobListNew;
CvMemStorage* m_pMem;
CvBlobTrackerOne* (*m_CreateCR)();
char m_ModuleName[1024];
public:
CvBlobTrackerCCCR(CvBlobTrackerOne* (*CreateCR)(), const char* CRName):m_BlobList(sizeof(DefBlobTrackerCR))
{
m_CreateCR = CreateCR;
m_pMem = cvCreateMemStorage();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
m_AlphaSize = 0.05f;
AddParam("AlphaSize",&m_AlphaSize);
CommentParam("AlphaSize", "Size update speed (0..1)");
strcpy(m_ModuleName, "CCCR");
if(CRName)strcat(m_ModuleName,CRName);
SetModuleName(m_ModuleName);
{
CvBlobTrackerOne* pM = m_CreateCR();
TransferParamsFromChild(pM,NULL);
pM->Release();
}
SetParam("SizeVar",0);
};
~CvBlobTrackerCCCR()
{
if(m_pMem)cvReleaseMemStorage(&m_pMem);
};
/* Blob functions: */
virtual int GetBlobNum() {return m_BlobList.GetBlobNum();};
virtual CvBlob* GetBlob(int BlobIndex){return m_BlobList.GetBlob(BlobIndex);};
virtual void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
if(pB) pB[0] = pBlob[0];
};
virtual CvBlob* GetBlobByID(int BlobID){return m_BlobList.GetBlobByID(BlobID);};
virtual void DelBlob(int BlobIndex)
{
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlob(BlobIndex);
if(pBT->pResolver)pBT->pResolver->Release();
if(pBT->pPredictor)pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlob(BlobIndex);
};
virtual void DelBlobByID(int BlobID)
{
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlobByID(BlobID);
if(pBT->pResolver)pBT->pResolver->Release();
if(pBT->pPredictor)pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlobByID(BlobID);
};
virtual void Release(){delete this;};
/* Add new blob to track it and assign to this blob personal ID */
/* pBlob - pinter 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* pB, IplImage* pImg, IplImage* pImgFG = NULL )
{
DefBlobTrackerCR NewB;
NewB.blob = pB[0];
NewB.pBlobHyp = new CvBlobSeq;
NewB.pPredictor = cvCreateModuleBlobTrackPredictKalman(); /* module for predict position */
NewB.pPredictor->SetParam("DataNoisePos",0.001);
NewB.pPredictor->ParamUpdate();
NewB.pResolver = NULL;
if(m_CreateCR)
{
NewB.pResolver = m_CreateCR();
TransferParamsToChild(NewB.pResolver,NULL);
NewB.pResolver->Init(pB, pImg, pImgFG);
}
m_BlobList.AddBlob((CvBlob*)&NewB);
return m_BlobList.GetBlob(m_BlobList.GetBlobNum()-1);
};
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
CvSeq* cnts;
CvSeq* cnt;
int i;
//CvMat* pMC = NULL;
if(m_BlobList.GetBlobNum() <= 0 ) return;
/* Clear blob list for new blobs: */
m_BlobListNew.Clear();
assert(m_pMem);
cvClearMemStorage(m_pMem);
assert(pImgFG);
{ /* One contour - one blob: */
IplImage* pBin = cvCloneImage(pImgFG);
assert(pBin);
cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* Process each contour: */
for(cnt = cnts; cnt; cnt=cnt->h_next)
{
CvBlob NewBlob;
/* Image moments: */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < 3 || r.width < 3) continue;
cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
m_BlobListNew.AddBlob(&NewBlob);
} /* Next contour. */
cvReleaseImage(&pBin);
}
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Predict new blob position. */
CvBlob* pB = NULL;
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);
/* Update predictor. */
pBT->pPredictor->Update(&(pBT->blob));
pB = pBT->pPredictor->Predict();
if(pB)
{
pBT->BlobPredict = pB[0];
}
pBT->BlobPrev = pBT->blob;
} /* Predict new blob position. */
if(m_BlobList.GetBlobNum()>0 && m_BlobListNew.GetBlobNum()>0)
{ /* Resolve new blob to old: */
int i,j;
int NOld = m_BlobList.GetBlobNum();
int NNew = m_BlobListNew.GetBlobNum();
for(i=0; i<NOld; i++)
{ /* Set 0 collision and clear all hyp: */
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
pF->Collision = 0;
pF->pBlobHyp->Clear();
} /* Set 0 collision. */
/* Create correspondence records: */
for(j=0; j<NNew; ++j)
{
CvBlob* pB1 = m_BlobListNew.GetBlob(j);
DefBlobTrackerCR* pFLast = NULL;
for(i=0; i<NOld; i++)
{ /* Check intersection: */
int Intersection = 0;
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
CvBlob* pB2 = &(pF->BlobPredict);
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Intersection = 1;
if(Intersection)
{
if(pFLast)
{
pF->Collision = pFLast->Collision = 1;
}
pFLast = pF;
pF->pBlobHyp->AddBlob(pB1);
}
} /* Check intersection. */
} /* Check next new blob. */
} /* Resolve new blob to old. */
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Track each blob. */
CvBlob* pB = m_BlobList.GetBlob(i-1);
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)pB;
int BlobID = CV_BLOB_ID(pB);
//CvBlob* pBBest = NULL;
//double DistBest = -1;
int j;
if(pBT->pResolver)
{
pBT->pResolver->SetCollision(pBT->Collision);
}
if(pBT->Collision)
{ /* Tracking in collision: */
if(pBT->pResolver)
{
pB[0] = pBT->pResolver->Process(&(pBT->BlobPredict),pImg, pImgFG)[0];
}
} /* Tracking in collision. */
else
{ /* Non-collision tracking: */
CvBlob NewCC = pBT->BlobPredict;
if(pBT->pBlobHyp->GetBlobNum()==1)
{ /* One blob to one CC: */
NewCC = pBT->pBlobHyp->GetBlob(0)[0];
}
else
{ /* One blob several CC: */
CvBlob* pBBest = NULL;
double DistBest = -1;
double CMax = 0;
for(j=pBT->pBlobHyp->GetBlobNum();j>0;--j)
{ /* Find best CC: */
CvBlob* pBNew = pBT->pBlobHyp->GetBlob(j-1);
if(pBT->pResolver)
{ /* Choose CC by confidence: */
// double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
// double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
double C = pBT->pResolver->GetConfidence(pBNew,pImg, pImgFG);
if(C > CMax || pBBest == NULL)
{
CMax = C;
pBBest = pBNew;
}
}
else
{ /* Choose CC by distance: */
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
double Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
}
} /* Find best CC. */
if(pBBest)
NewCC = pBBest[0];
} /* One blob several CC. */
pB->x = NewCC.x;
pB->y = NewCC.y;
pB->w = (m_AlphaSize)*NewCC.w+(1-m_AlphaSize)*pB->w;
pB->h = (m_AlphaSize)*NewCC.h+(1-m_AlphaSize)*pB->h;
pBT->pResolver->SkipProcess(&(pBT->BlobPredict),pImg, pImgFG);
} /* Non-collision tracking. */
pBT->pResolver->Update(pB, pImg, pImgFG);
CV_BLOB_ID(pB)=BlobID;
} /* Track next blob. */
if(m_Wnd)
{
IplImage* pI = cvCloneImage(pImg);
int i;
for(i=m_BlobListNew.GetBlobNum(); i>0; --i)
{ /* Draw each new CC: */
CvBlob* pB = m_BlobListNew.GetBlob(i-1);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
//int c = 255;
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(255,255,0), 1 );
}
for(i=m_BlobList.GetBlobNum(); i>0; --i)
{ /* Draw each new CC: */
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);
CvBlob* pB = &(pF->BlobPredict);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(0,0,255), 1 );
pB = &(pF->blob);
p = cvPointFrom32f(CV_BLOB_CENTER(pB));
x = cvRound(CV_BLOB_RX(pB)); y = cvRound(CV_BLOB_RY(pB));
s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(0,255,0), 1 );
}
//cvNamedWindow("CCwithCR",0);
//cvShowImage("CCwithCR",pI);
cvReleaseImage(&pI);
}
} /* Process. */
virtual void SaveState(CvFileStorage* fs)
{
int b,bN = m_BlobList.GetBlobNum();
cvWriteInt(fs,"BlobNum",m_BlobList.GetBlobNum());
cvStartWriteStruct(fs,"BlobList",CV_NODE_SEQ);
for(b=0; b<bN; ++b)
{
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(b);
cvStartWriteStruct(fs,NULL,CV_NODE_MAP);
cvWriteInt(fs,"ID",CV_BLOB_ID(pF));
cvStartWriteStruct(fs,"Blob",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->blob),1,"ffffi");
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"BlobPredict",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->BlobPredict),1,"ffffi");
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"BlobPrev",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->BlobPrev),1,"ffffi");
cvEndWriteStruct(fs);
pF->pBlobHyp->Write(fs,"BlobHyp");
cvWriteInt(fs,"Collision",pF->Collision);
cvStartWriteStruct(fs,"Predictor",CV_NODE_MAP);
pF->pPredictor->SaveState(fs);
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"Resolver",CV_NODE_MAP);
pF->pResolver->SaveState(fs);
cvEndWriteStruct(fs);
cvEndWriteStruct(fs);
}
cvEndWriteStruct(fs);
} /* SaveState. */
virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
{
int b,bN = cvReadIntByName(fs,node,"BlobNum",0);
CvFileNode* pBlobListNode = cvGetFileNodeByName(fs,node,"BlobList");
if(!CV_NODE_IS_SEQ(pBlobListNode->tag)) return;
bN = pBlobListNode->data.seq->total;
for(b=0; b<bN; ++b)
{
DefBlobTrackerCR* pF = NULL;
CvBlob Blob;
CvFileNode* pSeqNode = NULL;
CvFileNode* pBlobNode = (CvFileNode*)cvGetSeqElem(pBlobListNode->data.seq,b);
assert(pBlobNode);
Blob.ID = cvReadIntByName(fs,pBlobNode,"ID",0);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Blob");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &Blob, "ffffi" );
AddBlob(&Blob,NULL,NULL);
pF = (DefBlobTrackerCR*)m_BlobList.GetBlobByID(Blob.ID);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobPredict");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &pF->BlobPredict, "ffffi" );
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobPrev");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &pF->BlobPrev, "ffffi" );
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobHyp");
if(pSeqNode)
pF->pBlobHyp->Load(fs,pSeqNode);
pF->Collision = cvReadIntByName(fs, pBlobNode,"Collision",pF->Collision);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Predictor");
if(pSeqNode)
pF->pPredictor->LoadState(fs,pSeqNode);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Resolver");
if(pSeqNode)
pF->pResolver->LoadState(fs,pSeqNode);
} /* Read next blob. */
} /* CCwithCR LoadState */
//void SetCollision(int Collision){m_Collision = Collision;};
};
CvBlobTrackerOne* cvCreateBlobTrackerOneMSPF();
CvBlobTracker* cvCreateBlobTrackerCCMSPF()
{
return (CvBlobTracker*) new CvBlobTrackerCCCR(cvCreateBlobTrackerOneMSPF,"MSPF");
}
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */

View File

@@ -0,0 +1,173 @@
/*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
//
// 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*/
#include "precomp.hpp"
/*======================= KALMAN FILTER AS TRACKER =========================*/
/* State vector is (x,y,w,h,dx,dy,dw,dh). */
/* Measurement is (x,y,w,h) */
/* Dynamic matrix A: */
const float A8[] = { 1, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 1};
/* Measurement matrix H: */
const float H8[] = { 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0};
/* Matices for zero size velocity: */
/* Dynamic matrix A: */
const float A6[] = { 1, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1};
/* Measurement matrix H: */
const float H6[] = { 1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0};
#define STATE_NUM 6
#define A A6
#define H H6
class CvBlobTrackerOneKalman:public CvBlobTrackerOne
{
private:
CvBlob m_Blob;
CvKalman* m_pKalman;
int m_Frame;
public:
CvBlobTrackerOneKalman()
{
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(1e-5) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(1e-1) );
// CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) *= (float)pow(20,2);
// CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) *= (float)pow(20,2);
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
SetModuleName("Kalman");
}
~CvBlobTrackerOneKalman()
{
cvReleaseKalman(&m_pKalman);
}
virtual void Init(CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
m_Blob = pBlob[0];
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
virtual CvBlob* Process(CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
CvBlob* pBlobRes = &m_Blob;
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_Blob = pBlob[0];
if(m_Frame < 2)
{ /* First call: */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
memcpy(m_pKalman->state_pre->data.fl,m_pKalman->state_post->data.fl,sizeof(float)*STATE_NUM);
}
else
{ /* Another call: */
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
cvKalmanPredict(m_pKalman,0);
cvMatMulAdd(m_pKalman->measurement_matrix, m_pKalman->state_pre, NULL, &Zmat);
CV_BLOB_X(pBlobRes) = Z[0];
CV_BLOB_Y(pBlobRes) = Z[1];
CV_BLOB_WX(pBlobRes) = Z[2];
CV_BLOB_WY(pBlobRes) = Z[3];
}
m_Frame++;
return pBlobRes;
}
virtual void Release()
{
delete this;
}
}; /* class CvBlobTrackerOneKalman */
static CvBlobTrackerOne* cvCreateModuleBlobTrackerOneKalman()
{
return (CvBlobTrackerOne*) new CvBlobTrackerOneKalman;
}
CvBlobTracker* cvCreateBlobTrackerKalman()
{
return cvCreateBlobTrackerList(cvCreateModuleBlobTrackerOneKalman);
}

View File

@@ -0,0 +1,548 @@
/*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
//
// 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*/
#include "precomp.hpp"
#define PIX_HIST_BIN_NUM_1 3 //number of bins for classification (not used now)
#define PIX_HIST_BIN_NUM_2 5 //number of bins for statistic collection
#define PIX_HIST_ALPHA 0.01f //alpha-coefficient for running avarage procedure
#define PIX_HIST_DELTA 2 //maximal difference between descriptors(RGB)
#define PIX_HIST_COL_QUANTS 64 //quantization level in rgb-space
#define PIX_HIST_DELTA_IN_PIX_VAL (PIX_HIST_DELTA * 256 / PIX_HIST_COL_QUANTS) //allowed difference in rgb-space
// Structures for background statistics estimation:
typedef struct CvPixHistBin{
float bin_val;
uchar cols[3];
} CvPixHistBin;
typedef struct CvPixHist{
CvPixHistBin bins[PIX_HIST_BIN_NUM_2];
} CvPixHist;
// Class for background statistics estimation:
class CvBGEstimPixHist
{
private:
CvPixHist* m_PixHists;
int m_width;
int m_height;
// Function for update color histogram for one pixel:
void update_hist_elem(int x, int y, uchar* cols )
{
// Find closest bin:
int dist = 0, min_dist = 2147483647, indx = -1;
for( int k = 0; k < PIX_HIST_BIN_NUM_2; k++ ){
uchar* hist_cols = m_PixHists[y*m_width+x].bins[k].cols;
m_PixHists[y*m_width+x].bins[k].bin_val *= (1-PIX_HIST_ALPHA);
int l;
for( l = 0; l < 3; l++ ){
int val = abs( hist_cols[l] - cols[l] );
if( val > PIX_HIST_DELTA_IN_PIX_VAL ) break;
dist += val;
}
if( l == 3 && dist < min_dist ){
min_dist = dist;
indx = k;
}
}
if( indx < 0 ){ // N2th elem in the table is replaced by a new feature.
indx = PIX_HIST_BIN_NUM_2 - 1;
m_PixHists[y*m_width+x].bins[indx].bin_val = PIX_HIST_ALPHA;
for(int l = 0; l < 3; l++ ){
m_PixHists[y*m_width+x].bins[indx].cols[l] = cols[l];
}
}
else {
//add vote!
m_PixHists[y*m_width+x].bins[indx].bin_val += PIX_HIST_ALPHA;
}
// Re-sort bins by BIN_VAL:
{
int k;
for(k = 0; k < indx; k++ ){
if( m_PixHists[y*m_width+x].bins[k].bin_val <= m_PixHists[y*m_width+x].bins[indx].bin_val ){
CvPixHistBin tmp1, tmp2 = m_PixHists[y*m_width+x].bins[indx];
// Shift elements:
for(int l = k; l <= indx; l++ ){
tmp1 = m_PixHists[y*m_width+x].bins[l];
m_PixHists[y*m_width+x].bins[l] = tmp2;
tmp2 = tmp1;
}
break;
}
}
}
} // void update_hist(...)
// Function for calculation difference between histograms:
float get_hist_diff(int x1, int y1, int x2, int y2)
{
float dist = 0;
for( int i = 0; i < 3; i++ ){
dist += labs(m_PixHists[y1*m_width+x1].bins[0].cols[i] -
m_PixHists[y2*m_width+x2].bins[0].cols[i]);
}
return dist;
}
public:
IplImage* bg_image;
CvBGEstimPixHist(CvSize img_size)
{
m_PixHists = (CvPixHist*)cvAlloc(img_size.width*img_size.height*sizeof(CvPixHist));
memset( m_PixHists, 0, img_size.width*img_size.height*sizeof(CvPixHist) );
m_width = img_size.width;
m_height = img_size.height;
bg_image = cvCreateImage(img_size, IPL_DEPTH_8U, 3 );
} /* Constructor. */
~CvBGEstimPixHist()
{
cvReleaseImage(&bg_image);
cvFree(&m_PixHists);
} /* Destructor. */
// Function to update histograms and bg_image:
void update_hists( IplImage* pImg )
{
for( int i = 0; i < pImg->height; i++ ){
for( int j = 0; j < pImg->width; j++ ){
update_hist_elem( j, i, ((uchar*)(pImg->imageData))+i*pImg->widthStep+3*j );
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j] = m_PixHists[i*m_width+j].bins[0].cols[0];
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j+1] = m_PixHists[i*m_width+j].bins[0].cols[1];
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j+2] = m_PixHists[i*m_width+j].bins[0].cols[2];
}
}
// cvNamedWindow("RoadMap2",0);
// cvShowImage("RoadMap2", bg_image);
}
}; /* CvBGEstimPixHist */
/*======================= TRACKER LIST SHELL =====================*/
typedef struct DefBlobTrackerL
{
CvBlob blob;
CvBlobTrackerOne* pTracker;
int Frame;
int Collision;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
CvBlobSeq* pBlobHyp;
} DefBlobTrackerL;
class CvBlobTrackerList : public CvBlobTracker
{
private:
CvBlobTrackerOne* (*m_Create)();
CvBlobSeq m_BlobTrackerList;
// int m_LastID;
int m_Collision;
int m_ClearHyp;
float m_BGImageUsing;
CvBGEstimPixHist* m_pBGImage;
IplImage* m_pImgFG;
IplImage* m_pImgReg; /* mask for multiblob confidence calculation */
public:
CvBlobTrackerList(CvBlobTrackerOne* (*create)()):m_BlobTrackerList(sizeof(DefBlobTrackerL))
{
//int i;
CvBlobTrackerOne* pM = create();
// m_LastID = 0;
m_Create = create;
m_ClearHyp = 0;
m_pImgFG = 0;
m_pImgReg = NULL;
TransferParamsFromChild(pM,NULL);
pM->Release();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
AddParam("Collision",&m_Collision);
CommentParam("Collision", "if 1 then collision cases are processed in special way");
m_pBGImage = NULL;
m_BGImageUsing = 50;
AddParam("BGImageUsing", &m_BGImageUsing);
CommentParam("BGImageUsing","Weight of using BG image in update hist model (0 - BG dies not use 1 - use)");
SetModuleName("List");
}
~CvBlobTrackerList()
{
int i;
if(m_pBGImage) delete m_pBGImage;
if(m_pImgFG) cvReleaseImage(&m_pImgFG);
if(m_pImgReg) cvReleaseImage(&m_pImgReg);
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{
m_BlobTrackerList.DelBlob(i-1);
}
};
CvBlob* AddBlob(CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG )
{ /* Create new tracker: */
DefBlobTrackerL F;
F.blob = pBlob[0];
// F.blob.ID = m_LastID++;
F.pTracker = m_Create();
F.pPredictor = cvCreateModuleBlobTrackPredictKalman();
F.pBlobHyp = new CvBlobSeq;
F.Frame = 0;
TransferParamsToChild(F.pTracker,NULL);
F.pTracker->Init(pBlob,pImg, pImgFG);
m_BlobTrackerList.AddBlob((CvBlob*)&F);
return m_BlobTrackerList.GetBlob(m_BlobTrackerList.GetBlobNum()-1);
};
void DelBlob(int BlobIndex)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF == NULL) return;
pF->pTracker->Release();
pF->pPredictor->Release();
delete pF->pBlobHyp;
m_BlobTrackerList.DelBlob(BlobIndex);
}
void DelBlobByID(int BlobID)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlobByID(BlobID);
if(pF == NULL) return;
pF->pTracker->Release();
pF->pPredictor->Release();
delete pF->pBlobHyp;
m_BlobTrackerList.DelBlobByID(BlobID);
}
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
int i;
if(pImgFG)
{
if(m_pImgFG) cvCopy(pImgFG,m_pImgFG);
else m_pImgFG = cvCloneImage(pImgFG);
}
if(m_pBGImage==NULL && m_BGImageUsing>0)
{
m_pBGImage = new CvBGEstimPixHist(cvSize(pImg->width,pImg->height));
}
if(m_Collision)
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{ /* Update predictor: */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
pF->pPredictor->Update((CvBlob*)pF);
} /* Update predictor. */
if(m_pBGImage && m_pImgFG)
{ /* Weighting mask mask: */
int x,y,yN=pImg->height,xN=pImg->width;
IplImage* pImgBG = NULL;
m_pBGImage->update_hists(pImg);
pImgBG = m_pBGImage->bg_image;
for(y=0; y<yN; ++y)
{
unsigned char* pI = (unsigned char*)pImg->imageData + y*pImg->widthStep;
unsigned char* pBG = (unsigned char*)pImgBG->imageData + y*pImgBG->widthStep;
unsigned char* pFG = (unsigned char*)m_pImgFG->imageData +y*m_pImgFG->widthStep;
for(x=0; x<xN; ++x)
{
if(pFG[x])
{
int D1 = (int)(pI[3*x+0])-(int)(pBG[3*x+0]);
int D2 = (int)(pI[3*x+1])-(int)(pBG[3*x+1]);
int D3 = (int)(pI[3*x+2])-(int)(pBG[3*x+2]);
int DD = D1*D1+D2*D2+D3*D3;
double D = sqrt((float)DD);
double DW = 25;
double W = 1/(exp(-4*(D-m_BGImageUsing)/DW)+1);
pFG[x] = (uchar)cvRound(W*255);
}
} /* Next mask pixel. */
} /* Next mask line. */
/*if(m_Wnd)
{
cvNamedWindow("BlobList_FGWeight",0);
cvShowImage("BlobList_FGWeight",m_pImgFG);
}*/
} /* Weighting mask mask. */
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{ /* Predict position. */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
CvBlob* pB = pF->pPredictor->Predict();
if(pB)
{
pF->BlobPredict = pB[0];
pF->BlobPredict.w = pF->blob.w;
pF->BlobPredict.h = pF->blob.h;
}
} /* Predict position. */
if(m_Collision)
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{ /* Predict collision. */
int Collision = 0;
int j;
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
for(j=m_BlobTrackerList.GetBlobNum(); j>0; --j)
{ /* Predict collision. */
CvBlob* pB1;
CvBlob* pB2;
DefBlobTrackerL* pF2 = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(j-1);
if(i==j) continue;
pB1 = &pF->BlobPredict;
pB2 = &pF2->BlobPredict;
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Collision = 1;
pB1 = &pF->blob;
pB2 = &pF2->blob;
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Collision = 1;
if(Collision) break;
} /* Check next blob to cross current. */
pF->Collision = Collision;
pF->pTracker->SetCollision(Collision);
} /* Predict collision. */
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{ /* Track each blob. */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
if(pF->pBlobHyp->GetBlobNum()>0)
{ /* Track all hypothesis. */
int h,hN = pF->pBlobHyp->GetBlobNum();
for(h=0;h<hN;++h)
{
CvBlob* pB = pF->pBlobHyp->GetBlob(h);
CvBlob* pNewBlob = pF->pTracker->Process(pB,pImg,m_pImgFG);
int BlobID = CV_BLOB_ID(pB);
if(pNewBlob)
{
pB[0] = pNewBlob[0];
pB->w = MAX(CV_BLOB_MINW,pNewBlob->w);
pB->h = MAX(CV_BLOB_MINH,pNewBlob->h);
CV_BLOB_ID(pB) = BlobID;
}
} /* Next hypothesis. */
} /* Track all hypotheses. */
pF->Frame++;
} /* Next blob. */
#if 0
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{ /* Update predictor: */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
if((m_Collision && !pF->Collision) || !m_Collision)
{
pF->pPredictor->Update((CvBlob*)pF);
}
else
{ /* pravilnyp putem idete tovarischy!!! */
pF->pPredictor->Update(&(pF->BlobPredict));
}
} /* Update predictor. */
#endif
m_ClearHyp = 1;
};
/* Process on blob (for multi hypothesis tracing) */
virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* /*pImgFG*/ = NULL)
{
int ID = pBlob->ID;
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
CvBlob* pNewBlob = pF->pTracker->Process(pBlob?pBlob:&(pF->blob),pImg,m_pImgFG);
if(pNewBlob)
{
pF->blob = pNewBlob[0];
pF->blob.w = MAX(CV_BLOB_MINW,pNewBlob->w);
pF->blob.h = MAX(CV_BLOB_MINH,pNewBlob->h);
pBlob[0] = pF->blob;
}
pBlob->ID = ID;
};
virtual double GetConfidence(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG = NULL)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF==NULL) return 0;
if(pF->pTracker==NULL) return 0;
return pF->pTracker->GetConfidence(pBlob?pBlob:(&pF->blob), pImg, pImgFG, NULL);
};
virtual double GetConfidenceList(CvBlobSeq* pBlobList, IplImage* pImg, IplImage* pImgFG = NULL)
{
double W = 1;
int b,bN = pBlobList->GetBlobNum();
if(m_pImgReg == NULL)
{
m_pImgReg = cvCreateImage(cvSize(pImg->width,pImg->height),IPL_DEPTH_8U,1);
}
assert(pImg);
cvSet(m_pImgReg,cvScalar(255));
for(b=0; b<bN; ++b)
{
CvBlob* pB = pBlobList->GetBlob(b);
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlobByID(pB->ID);
if(pF==NULL || pF->pTracker==NULL) continue;
W *= pF->pTracker->GetConfidence(pB, pImg, pImgFG, m_pImgReg );
cvEllipse(
m_pImgReg,
cvPoint(cvRound(pB->x*256),cvRound(pB->y*256)), cvSize(cvRound(pB->w*128),cvRound(pB->h*128)),
0, 0, 360,
cvScalar(0), CV_FILLED, 8, 8 );
// cvNamedWindow("REG",0);
// cvShowImage("REG",m_pImgReg);
// cvWaitKey(0);
}
return W;
};
virtual void UpdateBlob(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* /*pImgFG*/ = NULL)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF)
{
pF->pTracker->Update(pBlob?pBlob:&(pF->blob),pImg,m_pImgFG);
}
};
int GetBlobNum(){return m_BlobTrackerList.GetBlobNum();};
CvBlob* GetBlob(int index){return m_BlobTrackerList.GetBlob(index);};
void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobTrackerList.GetBlob(BlobIndex);
if(pB)
{
pB[0] = pBlob[0];
pB->w = MAX(CV_BLOB_MINW, pBlob->w);
pB->h = MAX(CV_BLOB_MINH, pBlob->h);
}
}
void Release(){delete this;};
/* Additional functionality: */
CvBlob* GetBlobByID(int BlobID){return m_BlobTrackerList.GetBlobByID(BlobID);}
/* =============== MULTI HYPOTHESIS INTERFACE ================== */
/* Return number of position hypotheses of currently tracked blob: */
virtual int GetBlobHypNum(int BlobIdx)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIdx);
assert(pF->pBlobHyp);
return pF->pBlobHyp->GetBlobNum();
}; /* CvBlobtrackerList::GetBlobHypNum() */
/* Return pointer to specified blob hypothesis by index blob: */
virtual CvBlob* GetBlobHyp(int BlobIndex, int hypothesis)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
assert(pF->pBlobHyp);
return pF->pBlobHyp->GetBlob(hypothesis);
}; /* CvBlobtrackerList::GetBlobHyp() */
/* Set new parameters for specified (by index) blob hyp (can be called several times for each hyp )*/
virtual void SetBlobHyp(int BlobIndex, CvBlob* pBlob)
{
if(m_ClearHyp)
{ /* Clear all hypotheses: */
int b, bN = m_BlobTrackerList.GetBlobNum();
for(b=0; b<bN; ++b)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(b);
assert(pF->pBlobHyp);
pF->pBlobHyp->Clear();
}
m_ClearHyp = 0;
}
{ /* Add hypothesis: */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
assert(pF->pBlobHyp);
pF->pBlobHyp->AddBlob(pBlob);
}
}; /* CvBlobtrackerList::SetBlobHyp */
private:
public:
void ParamUpdate()
{
int i;
for(i=m_BlobTrackerList.GetBlobNum(); i>0; --i)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
TransferParamsToChild(pF->pTracker);
pF->pTracker->ParamUpdate();
}
}
}; /* CvBlobTrackerList */
CvBlobTracker* cvCreateBlobTrackerList(CvBlobTrackerOne* (*create)())
{
return (CvBlobTracker*) new CvBlobTrackerList(create);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,457 @@
/*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
//
// 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*/
#include "precomp.hpp"
#define SCALE_BASE 1.1
#define SCALE_RANGE 2
#define SCALE_NUM (2*SCALE_RANGE+1)
typedef float DefHistType;
#define DefHistTypeMat CV_32F
#define HIST_INDEX(_pData) (((_pData)[0]>>m_ByteShift) + (((_pData)[1]>>(m_ByteShift))<<m_BinBit)+((pImgData[2]>>m_ByteShift)<<(m_BinBit*2)))
void calcKernelEpanechnikov(CvMat* pK)
{ /* Allocate kernel for histogramm creation: */
int x,y;
int w = pK->width;
int h = pK->height;
float x0 = 0.5f*(w-1);
float y0 = 0.5f*(h-1);
for(y=0; y<h; ++y) for(x=0; x<w; ++x)
{
// float r2 = ((x-x0)*(x-x0)/(x0*x0)+(y-y0)*(y-y0)/(y0*y0));
float r2 = ((x-x0)*(x-x0)+(y-y0)*(y-y0))/((x0*x0)+(y0*y0));
CV_MAT_ELEM(pK[0],DefHistType, y, x) = (DefHistType)((r2<1)?(1-r2):0);
}
} /* Allocate kernel for histogram creation. */
class CvBlobTrackerOneMSFGS:public CvBlobTrackerOne
{
private:
/* Parameters: */
float m_FGWeight;
float m_Alpha;
CvSize m_ObjSize;
CvMat* m_KernelHistModel;
CvMat* m_KernelHistCandidate;
CvSize m_KernelMeanShiftSize;
CvMat* m_KernelMeanShiftK[SCALE_NUM];
CvMat* m_KernelMeanShiftG[SCALE_NUM];
CvMat* m_Weights;
int m_BinBit;
int m_ByteShift;
int m_BinNum;
int m_Dim;
int m_BinNumTotal;
CvMat* m_HistModel;
float m_HistModelVolume;
CvMat* m_HistCandidate;
float m_HistCandidateVolume;
CvMat* m_HistTemp;
CvBlob m_Blob;
void ReAllocHist(int Dim, int BinBit)
{
m_BinBit = BinBit;
m_ByteShift = 8-BinBit;
m_Dim = Dim;
m_BinNum = (1<<BinBit);
m_BinNumTotal = cvRound(pow((double)m_BinNum,(double)m_Dim));
if(m_HistModel) cvReleaseMat(&m_HistModel);
if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
if(m_HistTemp) cvReleaseMat(&m_HistTemp);
m_HistCandidate = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
m_HistModel = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
m_HistTemp = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
cvZero(m_HistCandidate);
cvZero(m_HistModel);
m_HistModelVolume = 0.0f;
m_HistCandidateVolume = 0.0f;
}
void ReAllocKernel(int w, int h, float sigma=0.4)
{
double ScaleToObj = sigma*1.39;
int kernel_width = cvRound(w/ScaleToObj);
int kernel_height = cvRound(h/ScaleToObj);
int x,y,s;
assert(w>0);
assert(h>0);
m_ObjSize = cvSize(w,h);
m_KernelMeanShiftSize = cvSize(kernel_width,kernel_height);
/* Create kernels for histogram calculation: */
if(m_KernelHistModel) cvReleaseMat(&m_KernelHistModel);
m_KernelHistModel = cvCreateMat(h, w, DefHistTypeMat);
calcKernelEpanechnikov(m_KernelHistModel);
if(m_KernelHistCandidate) cvReleaseMat(&m_KernelHistCandidate);
m_KernelHistCandidate = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
calcKernelEpanechnikov(m_KernelHistCandidate);
if(m_Weights) cvReleaseMat(&m_Weights);
m_Weights = cvCreateMat(kernel_height, kernel_width, CV_32F);
for(s=-SCALE_RANGE; s<=SCALE_RANGE; ++s)
{ /* Allocate kernel for meanshifts in space and scale: */
int si = s+SCALE_RANGE;
double cur_sigma = sigma * pow(SCALE_BASE,s);
double cur_sigma2 = cur_sigma*cur_sigma;
double x0 = 0.5*(kernel_width-1);
double y0 = 0.5*(kernel_height-1);
if(m_KernelMeanShiftK[si]) cvReleaseMat(&m_KernelMeanShiftK[si]);
if(m_KernelMeanShiftG[si]) cvReleaseMat(&m_KernelMeanShiftG[si]);
m_KernelMeanShiftK[si] = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
m_KernelMeanShiftG[si] = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
for(y=0; y<kernel_height; ++y)
{
DefHistType* pK = (DefHistType*)CV_MAT_ELEM_PTR_FAST( m_KernelMeanShiftK[si][0], y, 0, sizeof(DefHistType) );
DefHistType* pG = (DefHistType*)CV_MAT_ELEM_PTR_FAST( m_KernelMeanShiftG[si][0], y, 0, sizeof(DefHistType) );
for(x=0; x<kernel_width; ++x)
{
double r2 = ((x-x0)*(x-x0)/(x0*x0)+(y-y0)*(y-y0)/(y0*y0));
double sigma12 = cur_sigma2 / 2.56;
double sigma22 = cur_sigma2 * 2.56;
pK[x] = (DefHistType)(Gaussian2D(r2, sigma12)/sigma12 - Gaussian2D(r2, sigma22)/sigma22);
pG[x] = (DefHistType)(Gaussian2D(r2, cur_sigma2/1.6) - Gaussian2D(r2, cur_sigma2*1.6));
}
} /* Next line. */
}
} /* ReallocKernel */
inline double Gaussian2D(double x, double sigma2)
{
return (exp(-x/(2*sigma2)) / (2*3.1415926535897932384626433832795*sigma2) );
}
void calcHist(IplImage* pImg, IplImage* pMask, CvPoint Center, CvMat* pKernel, CvMat* pHist, DefHistType* pHistVolume)
{
int w = pKernel->width;
int h = pKernel->height;
DefHistType Volume = 0;
int x0 = Center.x - w/2;
int y0 = Center.y - h/2;
int x,y;
//cvZero(pHist);
cvSet(pHist,cvScalar(1.0/m_BinNumTotal)); /* no zero bins, all bins have very small value*/
Volume = 1;
if(m_Dim == 3)
{
for(y=0; y<h; ++y)
{
unsigned char* pImgData = NULL;
unsigned char* pMaskData = NULL;
DefHistType* pKernelData = NULL;
if((y0+y)>=pImg->height) continue;
if((y0+y)<0)continue;
pImgData = &CV_IMAGE_ELEM(pImg,unsigned char,y+y0,x0*3);
pMaskData = pMask?(&CV_IMAGE_ELEM(pMask,unsigned char,y+y0,x0)):NULL;
pKernelData = (DefHistType*)CV_MAT_ELEM_PTR_FAST(pKernel[0],y,0,sizeof(DefHistType));
for(x=0; x<w; ++x, pImgData+=3)
{
if((x0+x)>=pImg->width) continue;
if((x0+x)<0)continue;
if(pMaskData==NULL || pMaskData[x]>128)
{
DefHistType K = pKernelData[x];
int index = HIST_INDEX(pImgData);
assert(index >= 0 && index < pHist->cols);
Volume += K;
((DefHistType*)(pHist->data.ptr))[index] += K;
} /* Only masked pixels. */
} /* Next column. */
} /* Next row. */
} /* if m_Dim == 3. */
if(pHistVolume)pHistVolume[0] = Volume;
}; /* calcHist */
double calcBhattacharyya()
{
cvMul(m_HistCandidate,m_HistModel,m_HistTemp);
cvPow(m_HistTemp,m_HistTemp,0.5);
return cvSum(m_HistTemp).val[0] / sqrt(m_HistCandidateVolume*m_HistModelVolume);
} /* calcBhattacharyyaCoefficient */
void calcWeights(IplImage* pImg, IplImage* pImgFG, CvPoint Center)
{
cvZero(m_Weights);
/* Calculate new position: */
if(m_Dim == 3)
{
int x0 = Center.x - m_KernelMeanShiftSize.width/2;
int y0 = Center.y - m_KernelMeanShiftSize.height/2;
int x,y;
assert(m_Weights->width == m_KernelMeanShiftSize.width);
assert(m_Weights->height == m_KernelMeanShiftSize.height);
/* Calcualte shift vector: */
for(y=0; y<m_KernelMeanShiftSize.height; ++y)
{
unsigned char* pImgData = NULL;
unsigned char* pMaskData = NULL;
float* pWData = NULL;
if(y+y0 < 0 || y+y0 >= pImg->height) continue;
pImgData = &CV_IMAGE_ELEM(pImg,unsigned char,y+y0,x0*3);
pMaskData = pImgFG?(&CV_IMAGE_ELEM(pImgFG,unsigned char,y+y0,x0)):NULL;
pWData = (float*)CV_MAT_ELEM_PTR_FAST(m_Weights[0],y,0,sizeof(float));
for(x=0; x<m_KernelMeanShiftSize.width; ++x, pImgData+=3)
{
double V = 0;
double HM = 0;
double HC = 0;
int index;
if(x+x0 < 0 || x+x0 >= pImg->width) continue;
index = HIST_INDEX(pImgData);
assert(index >= 0 && index < m_BinNumTotal);
if(m_HistModelVolume>0)
HM = ((DefHistType*)m_HistModel->data.ptr)[index]/m_HistModelVolume;
if(m_HistCandidateVolume>0)
HC = ((DefHistType*)m_HistCandidate->data.ptr)[index]/m_HistCandidateVolume;
V = (HC>0)?sqrt(HM / HC):0;
V += m_FGWeight*(pMaskData?((pMaskData[x]/255.0f)):0);
pWData[x] = (float)MIN(V,100000);
} /* Next column. */
} /* Next row. */
} /* if m_Dim == 3. */
} /* calcWeights */
public:
CvBlobTrackerOneMSFGS()
{
int i;
m_FGWeight = 0;
m_Alpha = 0.0;
/* Add several parameters for external use: */
AddParam("FGWeight", &m_FGWeight);
CommentParam("FGWeight","Weight of FG mask using (0 - mask will not be used for tracking)");
AddParam("Alpha", &m_Alpha);
CommentParam("Alpha","Coefficient for model histogramm updating (0 - hist is not upated)");
m_BinBit=0;
m_Dim = 0;
m_HistModel = NULL;
m_HistCandidate = NULL;
m_HistTemp = NULL;
m_KernelHistModel = NULL;
m_KernelHistCandidate = NULL;
m_Weights = NULL;
for(i=0; i<SCALE_NUM; ++i)
{
m_KernelMeanShiftK[i] = NULL;
m_KernelMeanShiftG[i] = NULL;
}
ReAllocHist(3,5); /* 3D hist, each dimension has 2^5 bins. */
SetModuleName("MSFGS");
}
~CvBlobTrackerOneMSFGS()
{
int i;
if(m_HistModel) cvReleaseMat(&m_HistModel);
if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
if(m_HistTemp) cvReleaseMat(&m_HistTemp);
if(m_KernelHistModel) cvReleaseMat(&m_KernelHistModel);
for(i=0; i<SCALE_NUM; ++i)
{
if(m_KernelMeanShiftK[i]) cvReleaseMat(&m_KernelMeanShiftK[i]);
if(m_KernelMeanShiftG[i]) cvReleaseMat(&m_KernelMeanShiftG[i]);
}
}
/* Interface: */
virtual void Init(CvBlob* pBlobInit, IplImage* pImg, IplImage* pImgFG = NULL)
{
int w = cvRound(CV_BLOB_WX(pBlobInit));
int h = cvRound(CV_BLOB_WY(pBlobInit));
if(w<3)w=3;
if(h<3)h=3;
if(w>pImg->width)w=pImg->width;
if(h>pImg->height)h=pImg->height;
ReAllocKernel(w,h);
calcHist(pImg, pImgFG, cvPointFrom32f(CV_BLOB_CENTER(pBlobInit)), m_KernelHistModel, m_HistModel, &m_HistModelVolume);
m_Blob = pBlobInit[0];
};
virtual CvBlob* Process(CvBlob* pBlobPrev, IplImage* pImg, IplImage* pImgFG = NULL)
{
int iter;
if(pBlobPrev)
{
m_Blob = pBlobPrev[0];
}
for(iter=0; iter<10; ++iter)
{
// float newx=0,newy=0,sum=0;
float dx=0,dy=0,sum=0;
int x,y,si;
CvPoint Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
CvSize Size = cvSize(cvRound(m_Blob.w),cvRound(m_Blob.h));
if(m_ObjSize.width != Size.width || m_ObjSize.height != Size.height)
{ /* Reallocate kernels: */
ReAllocKernel(Size.width,Size.height);
} /* Reallocate kernels. */
/* Mean shift in coordinate space: */
calcHist(pImg, NULL, Center, m_KernelHistCandidate, m_HistCandidate, &m_HistCandidateVolume);
calcWeights(pImg, pImgFG, Center);
for(si=1; si<(SCALE_NUM-1); ++si)
{
CvMat* pKernel = m_KernelMeanShiftK[si];
float sdx = 0, sdy=0, ssum=0;
int s = si-SCALE_RANGE;
float factor = (1.0f-( float(s)/float(SCALE_RANGE) )*( float(s)/float(SCALE_RANGE) ));
for(y=0; y<m_KernelMeanShiftSize.height; ++y)
for(x=0; x<m_KernelMeanShiftSize.width; ++x)
{
float W = *(float*)CV_MAT_ELEM_PTR_FAST(m_Weights[0],y,x,sizeof(float));
float K = *(float*)CV_MAT_ELEM_PTR_FAST(pKernel[0],y,x,sizeof(float));
float KW = K*W;
ssum += (float)fabs(KW);
sdx += KW*(x-m_KernelMeanShiftSize.width*0.5f);
sdy += KW*(y-m_KernelMeanShiftSize.height*0.5f);
} /* Next pixel. */
dx += sdx * factor;
dy += sdy * factor;
sum += ssum * factor;
} /* Next scale. */
if(sum > 0)
{
dx /= sum;
dy /= sum;
}
m_Blob.x += dx;
m_Blob.y += dy;
{ /* Mean shift in scale space: */
float news = 0;
float sum = 0;
float scale;
Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
calcHist(pImg, NULL, Center, m_KernelHistCandidate, m_HistCandidate, &m_HistCandidateVolume);
calcWeights(pImg, pImgFG, Center);
//cvSet(m_Weights,cvScalar(1));
for(si=0; si<SCALE_NUM; si++)
{
double W = cvDotProduct(m_Weights, m_KernelMeanShiftG[si]);;
int s = si-SCALE_RANGE;
sum += (float)fabs(W);
news += (float)(s*W);
}
if(sum>0)
{
news /= sum;
}
scale = (float)pow((double)SCALE_BASE,(double)news);
m_Blob.w *= scale;
m_Blob.h *= scale;
} /* Mean shift in scale space. */
/* Check fo finish: */
if(fabs(dx)<0.1 && fabs(dy)<0.1) break;
} /* Next iteration. */
if(m_Alpha>0)
{ /* Update histogram: */
double Vol, WM, WC;
CvPoint Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
calcHist(pImg, pImgFG, Center, m_KernelHistModel, m_HistCandidate, &m_HistCandidateVolume);
Vol = 0.5*(m_HistModelVolume + m_HistCandidateVolume);
WM = Vol*(1-m_Alpha)/m_HistModelVolume;
WC = Vol*(m_Alpha)/m_HistCandidateVolume;
cvAddWeighted(m_HistModel, WM, m_HistCandidate,WC,0,m_HistModel);
m_HistModelVolume = (float)cvSum(m_HistModel).val[0];
} /* Update histogram. */
return &m_Blob;
}; /* Process */
virtual void Release(){delete this;};
}; /*CvBlobTrackerOneMSFGS*/
CvBlobTrackerOne* cvCreateBlobTrackerOneMSFGS()
{
return (CvBlobTrackerOne*) new CvBlobTrackerOneMSFGS;
}
CvBlobTracker* cvCreateBlobTrackerMSFGS()
{
return cvCreateBlobTrackerList(cvCreateBlobTrackerOneMSFGS);
}

View File

@@ -0,0 +1,327 @@
/*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
//
// 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*/
#include "precomp.hpp"
/*======================= KALMAN FILTER =========================*/
/* State vector is (x,y,w,h,dx,dy,dw,dh). */
/* Measurement is (x,y,w,h). */
/* Dynamic matrix A: */
const float A8[] = { 1, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 1};
/* Measurement matrix H: */
const float H8[] = { 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0};
/* Matrices for zero size velocity: */
/* Dinamic matrix A: */
const float A6[] = { 1, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1};
/* Measurement matrix H: */
const float H6[] = { 1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0};
#define STATE_NUM 6
#define A A6
#define H H6
class CvBlobTrackPostProcKalman:public CvBlobTrackPostProcOne
{
private:
CvBlob m_Blob;
CvKalman* m_pKalman;
int m_Frame;
float m_ModelNoise;
float m_DataNoisePos;
float m_DataNoiseSize;
public:
CvBlobTrackPostProcKalman();
~CvBlobTrackPostProcKalman();
CvBlob* Process(CvBlob* pBlob);
void Release();
virtual void ParamUpdate();
}; /* class CvBlobTrackPostProcKalman */
CvBlobTrackPostProcKalman::CvBlobTrackPostProcKalman()
{
m_ModelNoise = 1e-6f;
m_DataNoisePos = 1e-6f;
m_DataNoiseSize = 1e-1f;
#if STATE_NUM>6
m_DataNoiseSize *= (float)pow(20.,2.);
#else
m_DataNoiseSize /= (float)pow(20.,2.);
#endif
AddParam("ModelNoise",&m_ModelNoise);
AddParam("DataNoisePos",&m_DataNoisePos);
AddParam("DataNoiseSize",&m_DataNoiseSize);
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
SetModuleName("Kalman");
}
CvBlobTrackPostProcKalman::~CvBlobTrackPostProcKalman()
{
cvReleaseKalman(&m_pKalman);
}
void CvBlobTrackPostProcKalman::ParamUpdate()
{
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
}
CvBlob* CvBlobTrackPostProcKalman::Process(CvBlob* pBlob)
{
CvBlob* pBlobRes = &m_Blob;
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_Blob = pBlob[0];
if(m_Frame < 2)
{ /* First call: */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
else
{ /* Nonfirst call: */
cvKalmanPredict(m_pKalman,0);
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
cvMatMulAdd(m_pKalman->measurement_matrix, m_pKalman->state_post, NULL, &Zmat);
CV_BLOB_X(pBlobRes) = Z[0];
CV_BLOB_Y(pBlobRes) = Z[1];
// CV_BLOB_WX(pBlobRes) = Z[2];
// CV_BLOB_WY(pBlobRes) = Z[3];
}
m_Frame++;
return pBlobRes;
}
void CvBlobTrackPostProcKalman::Release()
{
delete this;
}
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcKalmanOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcKalman;
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcKalman()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcKalmanOne);
}
/*======================= KALMAN FILTER =========================*/
/*======================= KALMAN PREDICTOR =========================*/
class CvBlobTrackPredictKalman:public CvBlobTrackPredictor
{
private:
CvBlob m_BlobPredict;
CvKalman* m_pKalman;
int m_Frame;
float m_ModelNoise;
float m_DataNoisePos;
float m_DataNoiseSize;
public:
CvBlobTrackPredictKalman();
~CvBlobTrackPredictKalman();
CvBlob* Predict();
void Update(CvBlob* pBlob);
virtual void ParamUpdate();
void Release()
{
delete this;
}
}; /* class CvBlobTrackPredictKalman */
void CvBlobTrackPredictKalman::ParamUpdate()
{
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
}
CvBlobTrackPredictKalman::CvBlobTrackPredictKalman()
{
m_ModelNoise = 1e-6f;
m_DataNoisePos = 1e-6f;
m_DataNoiseSize = 1e-1f;
#if STATE_NUM>6
m_DataNoiseSize *= (float)pow(20.,2.);
#else
m_DataNoiseSize /= (float)pow(20.,2.);
#endif
AddParam("ModelNoise",&m_ModelNoise);
AddParam("DataNoisePos",&m_DataNoisePos);
AddParam("DataNoiseSize",&m_DataNoiseSize);
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
SetModuleName("Kalman");
}
CvBlobTrackPredictKalman::~CvBlobTrackPredictKalman()
{
cvReleaseKalman(&m_pKalman);
}
CvBlob* CvBlobTrackPredictKalman::Predict()
{
if(m_Frame >= 2)
{
cvKalmanPredict(m_pKalman,0);
m_BlobPredict.x = m_pKalman->state_pre->data.fl[0];
m_BlobPredict.y = m_pKalman->state_pre->data.fl[1];
m_BlobPredict.w = m_pKalman->state_pre->data.fl[2];
m_BlobPredict.h = m_pKalman->state_pre->data.fl[3];
}
return &m_BlobPredict;
}
void CvBlobTrackPredictKalman::Update(CvBlob* pBlob)
{
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_BlobPredict = pBlob[0];
if(m_Frame < 2)
{ /* First call: */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
else
{ /* Nonfirst call: */
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
}
cvKalmanPredict(m_pKalman,0);
m_Frame++;
} /* Update. */
CvBlobTrackPredictor* cvCreateModuleBlobTrackPredictKalman()
{
return (CvBlobTrackPredictor*) new CvBlobTrackPredictKalman;
}
/*======================= KALMAN PREDICTOR =========================*/

View File

@@ -0,0 +1,128 @@
/*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
//
// 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*/
#include "precomp.hpp"
/*======================= TIME AVERAGING FILTER =========================*/
#define TIME_WND 5
class CvBlobTrackPostProcTimeAver:public CvBlobTrackPostProcOne
{
protected:
CvBlob m_Blob;
CvBlob m_pBlobs[TIME_WND];
float m_Weights[TIME_WND];
int m_Frame;
public:
CvBlobTrackPostProcTimeAver( int KernelType = 0)
{
int i;
m_Frame = 0;
for(i=0;i<TIME_WND;++i)
{
m_Weights[i] = 1;
if(KernelType == 1)
{
m_Weights[i] = (float)exp((-2.3*i)/(TIME_WND-1)); /* last weight is 0.1 of first weight */
}
}
SetModuleName("TimeAver");
};
~CvBlobTrackPostProcTimeAver(){};
CvBlob* Process(CvBlob* pBlob)
{
float WSum = 0;
int i;
int index = m_Frame % TIME_WND;
int size = MIN((m_Frame+1), TIME_WND);
m_pBlobs[index] = pBlob[0];
m_Blob.x = m_Blob.y = m_Blob.w = m_Blob.h = 0;
for(i=0; i<size; ++i)
{
float W = m_Weights[i];
int index = (m_Frame - i + TIME_WND) % TIME_WND;
m_Blob.x += W*m_pBlobs[index].x;
m_Blob.y += W*m_pBlobs[index].y;
m_Blob.w += W*m_pBlobs[index].w;
m_Blob.h += W*m_pBlobs[index].h;
WSum += W;
}
assert(WSum>0);
m_Blob.x /= WSum;
m_Blob.y /= WSum;
m_Blob.w /= WSum;
m_Blob.h /= WSum;
m_Frame++;
return &m_Blob;
};
void Release()
{
delete this;
}
}; /* class CvBlobTrackPostProcTimeAver */
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcTimeAverRectOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcTimeAver(0);
}
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcTimeAverExpOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcTimeAver(1);
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverRect()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcTimeAverRectOne);
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverExp()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcTimeAverExpOne);
}
/*======================= KALMAN FILTER =========================*/

View File

@@ -0,0 +1,133 @@
/*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
//
// 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*/
#include "precomp.hpp"
/*======================= FILTER LIST SHELL =====================*/
typedef struct DefBlobFilter
{
CvBlob blob;
CvBlobTrackPostProcOne* pFilter;
int m_LastFrame;
} DefBlobFilter;
class CvBlobTrackPostProcList : public CvBlobTrackPostProc
{
protected:
CvBlobTrackPostProcOne* (*m_CreatePostProc)();
CvBlobSeq m_BlobFilterList;
int m_Frame;
public:
CvBlobTrackPostProcList(CvBlobTrackPostProcOne* (*create)()):m_BlobFilterList(sizeof(DefBlobFilter))
{
m_Frame = 0;
m_CreatePostProc = create;
CvBlobTrackPostProcOne* pM = create();
TransferParamsFromChild(pM,NULL);
pM->Release();
SetModuleName("List");
}
~CvBlobTrackPostProcList()
{
int i;
for(i=m_BlobFilterList.GetBlobNum();i>0;--i)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlob(i-1);
pF->pFilter->Release();
}
};
virtual void AddBlob(CvBlob* pBlob)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* Create new filter: */
DefBlobFilter F;
F.blob = pBlob[0];
F.m_LastFrame = m_Frame;
F.pFilter = m_CreatePostProc();
TransferParamsToChild(F.pFilter,NULL);
m_BlobFilterList.AddBlob((CvBlob*)&F);
pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
pF->blob = pBlob[0];
pF->m_LastFrame = m_Frame;
};
virtual void Process()
{
int i;
for(i=m_BlobFilterList.GetBlobNum(); i>0; --i)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlob(i-1);
if(pF->m_LastFrame == m_Frame)
{ /* Process: */
int ID = CV_BLOB_ID(pF);
pF->blob = *(pF->pFilter->Process(&(pF->blob)));
CV_BLOB_ID(pF) = ID;
}
else
{ /* Delete blob filter: */
pF->pFilter->Release();
m_BlobFilterList.DelBlob(i-1);
}
} /* Next blob. */
m_Frame++;
};
int GetBlobNum(){return m_BlobFilterList.GetBlobNum();};
CvBlob* GetBlob(int index){return m_BlobFilterList.GetBlob(index);};
void Release(){delete this;};
/* Additional functionality: */
CvBlob* GetBlobByID(int BlobID){return m_BlobFilterList.GetBlobByID(BlobID);}
}; /* CvBlobTrackPostProcList */
CvBlobTrackPostProc* cvCreateBlobTrackPostProcList(CvBlobTrackPostProcOne* (*create)())
{
return (CvBlobTrackPostProc*) new CvBlobTrackPostProcList(create);
}
/*======================= FILTER LIST SHELL =====================*/

View File

@@ -0,0 +1,684 @@
/*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.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2008-2010, Willow Garage Inc., 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*/
#include "precomp.hpp"
CvMat cvMatArray( int rows, int cols, int type,
int count, void* data)
{
return cvMat( rows*count, cols, type, data );
}
double cvMean( const CvArr* image, const CvArr* mask )
{
CvScalar mean = cvAvg( image, mask );
return mean.val[0];
}
double cvSumPixels( const CvArr* image )
{
CvScalar scalar = cvSum( image );
return scalar.val[0];
}
void cvMean_StdDev( const CvArr* image, double* mean, double* sdv, const CvArr* mask)
{
CvScalar _mean, _sdv;
cvAvgSdv( image, &_mean, &_sdv, mask );
if( mean )
*mean = _mean.val[0];
if( sdv )
*sdv = _sdv.val[0];
}
void cvmPerspectiveProject( const CvMat* mat, const CvArr* src, CvArr* dst )
{
CvMat tsrc, tdst;
cvReshape( src, &tsrc, 3, 0 );
cvReshape( dst, &tdst, 3, 0 );
cvPerspectiveTransform( &tsrc, &tdst, mat );
}
void cvFillImage( CvArr* mat, double color )
{
cvSet( mat, cvColorToScalar(color, cvGetElemType(mat)), 0 );
}
/* Changes RNG range while preserving RNG state */
void cvRandSetRange( CvRandState* state, double param1, double param2, int index)
{
if( !state )
{
cvError( CV_StsNullPtr, "cvRandSetRange", "Null pointer to RNG state", "cvcompat.h", 0 );
return;
}
if( (unsigned)(index + 1) > 4 )
{
cvError( CV_StsOutOfRange, "cvRandSetRange", "index is not in -1..3", "cvcompat.h", 0 );
return;
}
if( index < 0 )
{
state->param[0].val[0] = state->param[0].val[1] =
state->param[0].val[2] = state->param[0].val[3] = param1;
state->param[1].val[0] = state->param[1].val[1] =
state->param[1].val[2] = state->param[1].val[3] = param2;
}
else
{
state->param[0].val[index] = param1;
state->param[1].val[index] = param2;
}
}
void cvRandInit( CvRandState* state, double param1, double param2,
int seed, int disttype)
{
if( !state )
{
cvError( CV_StsNullPtr, "cvRandInit", "Null pointer to RNG state", "cvcompat.h", 0 );
return;
}
if( disttype != CV_RAND_UNI && disttype != CV_RAND_NORMAL )
{
cvError( CV_StsBadFlag, "cvRandInit", "Unknown distribution type", "cvcompat.h", 0 );
return;
}
state->state = (uint64)(seed ? seed : -1);
state->disttype = disttype;
cvRandSetRange( state, param1, param2, -1 );
}
/* Fills array with random numbers */
void cvRand( CvRandState* state, CvArr* arr )
{
if( !state )
{
cvError( CV_StsNullPtr, "cvRand", "Null pointer to RNG state", "cvcompat.h", 0 );
return;
}
cvRandArr( &state->state, arr, state->disttype, state->param[0], state->param[1] );
}
void cvbRand( CvRandState* state, float* dst, int len )
{
CvMat mat = cvMat( 1, len, CV_32F, (void*)dst );
cvRand( state, &mat );
}
void cvbCartToPolar( const float* y, const float* x, float* magnitude, float* angle, int len )
{
CvMat mx = cvMat( 1, len, CV_32F, (void*)x );
CvMat my = mx;
CvMat mm = mx;
CvMat ma = mx;
my.data.fl = (float*)y;
mm.data.fl = (float*)magnitude;
ma.data.fl = (float*)angle;
cvCartToPolar( &mx, &my, &mm, angle ? &ma : NULL, 1 );
}
void cvbFastArctan( const float* y, const float* x, float* angle, int len )
{
CvMat mx = cvMat( 1, len, CV_32F, (void*)x );
CvMat my = mx;
CvMat ma = mx;
my.data.fl = (float*)y;
ma.data.fl = (float*)angle;
cvCartToPolar( &mx, &my, NULL, &ma, 1 );
}
void cvbSqrt( const float* x, float* y, int len )
{
CvMat mx = cvMat( 1, len, CV_32F, (void*)x );
CvMat my = mx;
my.data.fl = (float*)y;
cvPow( &mx, &my, 0.5 );
}
void cvbInvSqrt( const float* x, float* y, int len )
{
CvMat mx = cvMat( 1, len, CV_32F, (void*)x );
CvMat my = mx;
my.data.fl = (float*)y;
cvPow( &mx, &my, -0.5 );
}
void cvbReciprocal( const float* x, float* y, int len )
{
CvMat mx = cvMat( 1, len, CV_32F, (void*)x );
CvMat my = mx;
my.data.fl = (float*)y;
cvPow( &mx, &my, -1 );
}
void cvbFastExp( const float* x, double* y, int len )
{
int i;
for( i = 0; i < len; i++ )
y[i] = exp((double)x[i]);
}
void cvbFastLog( const double* x, float* y, int len )
{
int i;
for( i = 0; i < len; i++ )
y[i] = (float)log(x[i]);
}
CvRect cvContourBoundingRect( void* point_set, int update)
{
return cvBoundingRect( point_set, update );
}
double cvPseudoInverse( const CvArr* src, CvArr* dst )
{
return cvInvert( src, dst, CV_SVD );
}
/* Calculates exact convex hull of 2d point set */
void cvConvexHull( CvPoint* points, int num_points, CvRect*,
int orientation, int* hull, int* hullsize )
{
CvMat points1 = cvMat( 1, num_points, CV_32SC2, points );
CvMat hull1 = cvMat( 1, num_points, CV_32SC1, hull );
cvConvexHull2( &points1, &hull1, orientation, 0 );
*hullsize = hull1.cols;
}
void cvMinAreaRect( CvPoint* points, int n, int, int, int, int,
CvPoint2D32f* anchor, CvPoint2D32f* vect1, CvPoint2D32f* vect2 )
{
CvMat mat = cvMat( 1, n, CV_32SC2, points );
CvBox2D box = cvMinAreaRect2( &mat, 0 );
CvPoint2D32f pt[4];
cvBoxPoints( box, pt );
*anchor = pt[0];
vect1->x = pt[1].x - pt[0].x;
vect1->y = pt[1].y - pt[0].y;
vect2->x = pt[3].x - pt[0].x;
vect2->y = pt[3].y - pt[0].y;
}
void cvFitLine3D( CvPoint3D32f* points, int count, int dist,
void *param, float reps, float aeps, float* line )
{
CvMat mat = cvMat( 1, count, CV_32FC3, points );
float _param = param != NULL ? *(float*)param : 0.f;
assert( dist != CV_DIST_USER );
cvFitLine( &mat, dist, _param, reps, aeps, line );
}
/* Fits a line into set of 2d points in a robust way (M-estimator technique) */
void cvFitLine2D( CvPoint2D32f* points, int count, int dist,
void *param, float reps, float aeps, float* line )
{
CvMat mat = cvMat( 1, count, CV_32FC2, points );
float _param = param != NULL ? *(float*)param : 0.f;
assert( dist != CV_DIST_USER );
cvFitLine( &mat, dist, _param, reps, aeps, line );
}
void cvFitEllipse( const CvPoint2D32f* points, int count, CvBox2D* box )
{
CvMat mat = cvMat( 1, count, CV_32FC2, (void*)points );
*box = cvFitEllipse2( &mat );
}
/* Projects 2d points to one of standard coordinate planes
(i.e. removes one of coordinates) */
void cvProject3D( CvPoint3D32f* points3D, int count,
CvPoint2D32f* points2D, int xIndx, int yIndx)
{
CvMat src = cvMat( 1, count, CV_32FC3, points3D );
CvMat dst = cvMat( 1, count, CV_32FC2, points2D );
float m[6] = {0,0,0,0,0,0};
CvMat M = cvMat( 2, 3, CV_32F, m );
assert( (unsigned)xIndx < 3 && (unsigned)yIndx < 3 );
m[xIndx] = m[yIndx+3] = 1.f;
cvTransform( &src, &dst, &M, NULL );
}
int cvHoughLines( CvArr* image, double rho,
double theta, int threshold,
float* lines, int linesNumber )
{
CvMat linesMat = cvMat( 1, linesNumber, CV_32FC2, lines );
cvHoughLines2( image, &linesMat, CV_HOUGH_STANDARD,
rho, theta, threshold, 0, 0 );
return linesMat.cols;
}
int cvHoughLinesP( CvArr* image, double rho,
double theta, int threshold,
int lineLength, int lineGap,
int* lines, int linesNumber )
{
CvMat linesMat = cvMat( 1, linesNumber, CV_32SC4, lines );
cvHoughLines2( image, &linesMat, CV_HOUGH_PROBABILISTIC,
rho, theta, threshold, lineLength, lineGap );
return linesMat.cols;
}
int cvHoughLinesSDiv( CvArr* image, double rho, int srn,
double theta, int stn, int threshold,
float* lines, int linesNumber )
{
CvMat linesMat = cvMat( 1, linesNumber, CV_32FC2, lines );
cvHoughLines2( image, &linesMat, CV_HOUGH_MULTI_SCALE,
rho, theta, threshold, srn, stn );
return linesMat.cols;
}
float cvCalcEMD( const float* signature1, int size1, const float* signature2, int size2,
int dims, int dist_type, CvDistanceFunction dist_func,
float* lower_bound, void* user_param)
{
CvMat sign1 = cvMat( size1, dims + 1, CV_32FC1, (void*)signature1 );
CvMat sign2 = cvMat( size2, dims + 1, CV_32FC1, (void*)signature2 );
return cvCalcEMD2( &sign1, &sign2, dist_type, dist_func, 0, 0, lower_bound, user_param );
}
void cvKMeans( int num_clusters, float** samples,
int num_samples, int vec_size,
CvTermCriteria termcrit, int* cluster_idx )
{
CvMat* samples_mat = cvCreateMat( num_samples, vec_size, CV_32FC1 );
CvMat cluster_idx_mat = cvMat( num_samples, 1, CV_32SC1, cluster_idx );
int i;
for( i = 0; i < num_samples; i++ )
memcpy( samples_mat->data.fl + i*vec_size, samples[i], vec_size*sizeof(float));
cvKMeans2( samples_mat, num_clusters, &cluster_idx_mat, termcrit, 1, 0, 0, 0, 0 );
cvReleaseMat( &samples_mat );
}
void cvStartScanGraph( CvGraph* graph, CvGraphScanner* scanner,
CvGraphVtx* vtx, int mask)
{
CvGraphScanner* temp_scanner;
if( !scanner )
cvError( CV_StsNullPtr, "cvStartScanGraph", "Null scanner pointer", "cvcompat.h", 0 );
temp_scanner = cvCreateGraphScanner( graph, vtx, mask );
*scanner = *temp_scanner;
cvFree( &temp_scanner );
}
void cvEndScanGraph( CvGraphScanner* scanner )
{
if( !scanner )
cvError( CV_StsNullPtr, "cvEndScanGraph", "Null scanner pointer", "cvcompat.h", 0 );
if( scanner->stack )
{
CvGraphScanner* temp_scanner = (CvGraphScanner*)cvAlloc( sizeof(*temp_scanner) );
*temp_scanner = *scanner;
cvReleaseGraphScanner( &temp_scanner );
memset( scanner, 0, sizeof(*scanner) );
}
}
/* old drawing functions */
void cvLineAA( CvArr* img, CvPoint pt1, CvPoint pt2, double color, int scale)
{
cvLine( img, pt1, pt2, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
void cvCircleAA( CvArr* img, CvPoint center, int radius, double color, int scale)
{
cvCircle( img, center, radius, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
void cvEllipseAA( CvArr* img, CvPoint center, CvSize axes,
double angle, double start_angle,
double end_angle, double color,
int scale)
{
cvEllipse( img, center, axes, angle, start_angle, end_angle,
cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
void cvPolyLineAA( CvArr* img, CvPoint** pts, int* npts, int contours,
int is_closed, double color, int scale )
{
cvPolyLine( img, pts, npts, contours, is_closed,
cvColorToScalar(color, cvGetElemType(img)),
1, CV_AA, scale );
}
void cvUnDistortOnce( const CvArr* src, CvArr* dst,
const float* intrinsic_matrix,
const float* distortion_coeffs,
int )
{
CvMat _a = cvMat( 3, 3, CV_32F, (void*)intrinsic_matrix );
CvMat _k = cvMat( 4, 1, CV_32F, (void*)distortion_coeffs );
cvUndistort2( src, dst, &_a, &_k, 0 );
}
/* the two functions below have quite hackerish implementations, use with care
(or, which is better, switch to cvUndistortInitMap and cvRemap instead */
void cvUnDistortInit( const CvArr*,
CvArr* undistortion_map,
const float* A, const float* k,
int)
{
union { uchar* ptr; float* fl; } data;
CvSize sz;
cvGetRawData( undistortion_map, &data.ptr, 0, &sz );
assert( sz.width >= 8 );
/* just save the intrinsic parameters to the map */
data.fl[0] = A[0]; data.fl[1] = A[4];
data.fl[2] = A[2]; data.fl[3] = A[5];
data.fl[4] = k[0]; data.fl[5] = k[1];
data.fl[6] = k[2]; data.fl[7] = k[3];
}
void cvUnDistort( const CvArr* src, CvArr* dst,
const CvArr* undistortion_map, int )
{
union { uchar* ptr; float* fl; } data;
float a[] = {0,0,0,0,0,0,0,0,1};
CvSize sz;
cvGetRawData( undistortion_map, &data.ptr, 0, &sz );
assert( sz.width >= 8 );
a[0] = data.fl[0]; a[4] = data.fl[1];
a[2] = data.fl[2]; a[5] = data.fl[3];
cvUnDistortOnce( src, dst, a, data.fl + 4, 1 );
}
/* Find fundamental matrix */
void cvFindFundamentalMatrix( int* points1, int* points2, int numpoints, int, float* matrix )
{
CvMat* pointsMat1;
CvMat* pointsMat2;
CvMat fundMatr = cvMat(3,3,CV_32F,matrix);
int i, curr = 0;
pointsMat1 = cvCreateMat(3,numpoints,CV_64F);
pointsMat2 = cvCreateMat(3,numpoints,CV_64F);
for( i = 0; i < numpoints; i++ )
{
cvmSet(pointsMat1,0,i,points1[curr]);//x
cvmSet(pointsMat1,1,i,points1[curr+1]);//y
cvmSet(pointsMat1,2,i,1.0);
cvmSet(pointsMat2,0,i,points2[curr]);//x
cvmSet(pointsMat2,1,i,points2[curr+1]);//y
cvmSet(pointsMat2,2,i,1.0);
curr += 2;
}
cvFindFundamentalMat(pointsMat1,pointsMat2,&fundMatr,CV_FM_RANSAC,1,0.99,0);
cvReleaseMat(&pointsMat1);
cvReleaseMat(&pointsMat2);
}
int cvFindChessBoardCornerGuesses( const void* arr, void*,
CvMemStorage*, CvSize pattern_size,
CvPoint2D32f* corners, int* corner_count )
{
return cvFindChessboardCorners( arr, pattern_size, corners,
corner_count, CV_CALIB_CB_ADAPTIVE_THRESH );
}
/* Calibrates camera using multiple views of calibration pattern */
void cvCalibrateCamera( int image_count, int* _point_counts,
CvSize image_size, CvPoint2D32f* _image_points, CvPoint3D32f* _object_points,
float* _distortion_coeffs, float* _camera_matrix, float* _translation_vectors,
float* _rotation_matrices, int flags )
{
int i, total = 0;
CvMat point_counts = cvMat( image_count, 1, CV_32SC1, _point_counts );
CvMat image_points, object_points;
CvMat dist_coeffs = cvMat( 4, 1, CV_32FC1, _distortion_coeffs );
CvMat camera_matrix = cvMat( 3, 3, CV_32FC1, _camera_matrix );
CvMat rotation_matrices = cvMat( image_count, 9, CV_32FC1, _rotation_matrices );
CvMat translation_vectors = cvMat( image_count, 3, CV_32FC1, _translation_vectors );
for( i = 0; i < image_count; i++ )
total += _point_counts[i];
image_points = cvMat( total, 1, CV_32FC2, _image_points );
object_points = cvMat( total, 1, CV_32FC3, _object_points );
cvCalibrateCamera2( &object_points, &image_points, &point_counts, image_size,
&camera_matrix, &dist_coeffs, &rotation_matrices, &translation_vectors,
flags );
}
void cvCalibrateCamera_64d( int image_count, int* _point_counts,
CvSize image_size, CvPoint2D64f* _image_points, CvPoint3D64f* _object_points,
double* _distortion_coeffs, double* _camera_matrix, double* _translation_vectors,
double* _rotation_matrices, int flags )
{
int i, total = 0;
CvMat point_counts = cvMat( image_count, 1, CV_32SC1, _point_counts );
CvMat image_points, object_points;
CvMat dist_coeffs = cvMat( 4, 1, CV_64FC1, _distortion_coeffs );
CvMat camera_matrix = cvMat( 3, 3, CV_64FC1, _camera_matrix );
CvMat rotation_matrices = cvMat( image_count, 9, CV_64FC1, _rotation_matrices );
CvMat translation_vectors = cvMat( image_count, 3, CV_64FC1, _translation_vectors );
for( i = 0; i < image_count; i++ )
total += _point_counts[i];
image_points = cvMat( total, 1, CV_64FC2, _image_points );
object_points = cvMat( total, 1, CV_64FC3, _object_points );
cvCalibrateCamera2( &object_points, &image_points, &point_counts, image_size,
&camera_matrix, &dist_coeffs, &rotation_matrices, &translation_vectors,
flags );
}
/* Find 3d position of object given intrinsic camera parameters,
3d model of the object and projection of the object into view plane */
void cvFindExtrinsicCameraParams( int point_count,
CvSize image_size, CvPoint2D32f* _image_points,
CvPoint3D32f* _object_points, float* focal_length,
CvPoint2D32f principal_point, float* _distortion_coeffs,
float* _rotation_vector, float* _translation_vector )
{
CvMat image_points = cvMat( point_count, 1, CV_32FC2, _image_points );
CvMat object_points = cvMat( point_count, 1, CV_32FC3, _object_points );
CvMat dist_coeffs = cvMat( 4, 1, CV_32FC1, _distortion_coeffs );
float a[9];
CvMat camera_matrix = cvMat( 3, 3, CV_32FC1, a );
CvMat rotation_vector = cvMat( 1, 1, CV_32FC3, _rotation_vector );
CvMat translation_vector = cvMat( 1, 1, CV_32FC3, _translation_vector );
a[0] = focal_length[0]; a[4] = focal_length[1];
a[2] = principal_point.x; a[5] = principal_point.y;
a[1] = a[3] = a[6] = a[7] = 0.f;
a[8] = 1.f;
cvFindExtrinsicCameraParams2( &object_points, &image_points, &camera_matrix,
&dist_coeffs, &rotation_vector, &translation_vector, 0 );
}
/* Variant of the previous function that takes double-precision parameters */
void cvFindExtrinsicCameraParams_64d( int point_count,
CvSize image_size, CvPoint2D64f* _image_points,
CvPoint3D64f* _object_points, double* focal_length,
CvPoint2D64f principal_point, double* _distortion_coeffs,
double* _rotation_vector, double* _translation_vector )
{
CvMat image_points = cvMat( point_count, 1, CV_64FC2, _image_points );
CvMat object_points = cvMat( point_count, 1, CV_64FC3, _object_points );
CvMat dist_coeffs = cvMat( 4, 1, CV_64FC1, _distortion_coeffs );
double a[9];
CvMat camera_matrix = cvMat( 3, 3, CV_64FC1, a );
CvMat rotation_vector = cvMat( 1, 1, CV_64FC3, _rotation_vector );
CvMat translation_vector = cvMat( 1, 1, CV_64FC3, _translation_vector );
a[0] = focal_length[0]; a[4] = focal_length[1];
a[2] = principal_point.x; a[5] = principal_point.y;
a[1] = a[3] = a[6] = a[7] = 0.;
a[8] = 1.;
cvFindExtrinsicCameraParams2( &object_points, &image_points, &camera_matrix,
&dist_coeffs, &rotation_vector, &translation_vector, 0 );
}
/* Converts rotation_matrix matrix to rotation_matrix vector or vice versa */
void cvRodrigues( CvMat* rotation_matrix, CvMat* rotation_vector,
CvMat* jacobian, int conv_type )
{
if( conv_type == CV_RODRIGUES_V2M )
cvRodrigues2( rotation_vector, rotation_matrix, jacobian );
else
cvRodrigues2( rotation_matrix, rotation_vector, jacobian );
}
/* Does reprojection of 3d object points to the view plane */
void cvProjectPoints( int point_count, CvPoint3D64f* _object_points,
double* _rotation_vector, double* _translation_vector,
double* focal_length, CvPoint2D64f principal_point,
double* _distortion, CvPoint2D64f* _image_points,
double* _deriv_points_rotation_matrix,
double* _deriv_points_translation_vect,
double* _deriv_points_focal,
double* _deriv_points_principal_point,
double* _deriv_points_distortion_coeffs )
{
CvMat object_points = cvMat( point_count, 1, CV_64FC3, _object_points );
CvMat image_points = cvMat( point_count, 1, CV_64FC2, _image_points );
CvMat rotation_vector = cvMat( 3, 1, CV_64FC1, _rotation_vector );
CvMat translation_vector = cvMat( 3, 1, CV_64FC1, _translation_vector );
double a[9];
CvMat camera_matrix = cvMat( 3, 3, CV_64FC1, a );
CvMat dist_coeffs = cvMat( 4, 1, CV_64FC1, _distortion );
CvMat dpdr = cvMat( 2*point_count, 3, CV_64FC1, _deriv_points_rotation_matrix );
CvMat dpdt = cvMat( 2*point_count, 3, CV_64FC1, _deriv_points_translation_vect );
CvMat dpdf = cvMat( 2*point_count, 2, CV_64FC1, _deriv_points_focal );
CvMat dpdc = cvMat( 2*point_count, 2, CV_64FC1, _deriv_points_principal_point );
CvMat dpdk = cvMat( 2*point_count, 4, CV_64FC1, _deriv_points_distortion_coeffs );
a[0] = focal_length[0]; a[4] = focal_length[1];
a[2] = principal_point.x; a[5] = principal_point.y;
a[1] = a[3] = a[6] = a[7] = 0.;
a[8] = 1.;
cvProjectPoints2( &object_points, &rotation_vector, &translation_vector,
&camera_matrix, &dist_coeffs, &image_points,
&dpdr, &dpdt, &dpdf, &dpdc, &dpdk, 0 );
}
/* Simpler version of the previous function */
void cvProjectPointsSimple( int point_count, CvPoint3D64f* _object_points,
double* _rotation_matrix, double* _translation_vector,
double* _camera_matrix, double* _distortion, CvPoint2D64f* _image_points )
{
CvMat object_points = cvMat( point_count, 1, CV_64FC3, _object_points );
CvMat image_points = cvMat( point_count, 1, CV_64FC2, _image_points );
CvMat rotation_matrix = cvMat( 3, 3, CV_64FC1, _rotation_matrix );
CvMat translation_vector = cvMat( 3, 1, CV_64FC1, _translation_vector );
CvMat camera_matrix = cvMat( 3, 3, CV_64FC1, _camera_matrix );
CvMat dist_coeffs = cvMat( 4, 1, CV_64FC1, _distortion );
cvProjectPoints2( &object_points, &rotation_matrix, &translation_vector,
&camera_matrix, &dist_coeffs, &image_points,
0, 0, 0, 0, 0, 0 );
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
/*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
//
// 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*/
/*
This file contain implementation of virtual interface of CvBlobDetector
this implementation based on simple algorithm
new blob is detected when several successive frames contains connected componets
which have uniform motion with not high speed.
Also separation from border and already tracked blobs are considered.
*/
#include "precomp.hpp"
/* blob detector based on real data (groundtruth data)*/
class CvBlobDetectorReal:public CvBlobDetector
{
protected:
CvTestSeq* m_pTestSeq;
CvBlobSeq m_DetectedBlobs;
CvMemStorage* m_pMem;
public:
CvBlobDetectorReal(CvTestSeq* pTestSeq)
{
m_pTestSeq = pTestSeq;
m_pMem = cvCreateMemStorage(0);
SetModuleName("Real");
}
/* Destructor of BlobDetector: */
~CvBlobDetectorReal()
{
if(m_pMem) cvReleaseMemStorage(&m_pMem);
} /* cvReleaseBlobDetector */
/* cvDetectNewBlobs:
* Return 1 and fill blob pNewBlob with
* blob parameters if new blob is detected:
*/
int DetectNewBlob(IplImage* /*pImg*/, IplImage* /*pFGMask*/, CvBlobSeq* pNewBlobList, CvBlobSeq* /*pOldBlobList*/)
{
int i;
int TestObjNum;
IplImage* pMask = NULL;
IplImage* pMaskCopy = NULL;
CvSeq* cnts = NULL;
if(m_pTestSeq==NULL) return 0;
TestObjNum = cvTestSeqGetObjectNum(m_pTestSeq);
pMask = cvTestSeqGetFGMask(m_pTestSeq);
if(pMask == NULL) return 0;
pMaskCopy = cvCloneImage(pMask);
assert(pMaskCopy);
cvClearMemStorage(m_pMem);
cvFindContours( pMaskCopy, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
cvReleaseImage(&pMaskCopy);
for(i=0; i<TestObjNum; ++i)
{ /* Check each object: */
CvPoint2D32f RealPos;
CvPoint2D32f RealSize;
int RealPosFlag = cvTestSeqGetObjectPos(m_pTestSeq,i,&RealPos);
int RealSizeFlag = cvTestSeqGetObjectSize(m_pTestSeq,i,&RealSize);
if(!RealPosFlag) continue;
if(m_DetectedBlobs.GetBlobByID(i)) continue;
if(RealSizeFlag)
{ /* Real size is known: */
float W2 = RealSize.x * 0.5f;
float H2 = RealSize.y * 0.5f;
if( RealPos.x > W2 && RealPos.x < (pMask->width-W2) &&
RealPos.y > H2 && RealPos.y < (pMask->height-H2) )
{ /* Yes!! We found new blob, let's add it to list: */
CvBlob NewBlob;
NewBlob.x = RealPos.x;
NewBlob.y = RealPos.y;
NewBlob.w = RealSize.x;
NewBlob.h = RealSize.y;
NewBlob.ID = i;
m_DetectedBlobs.AddBlob(&NewBlob);
pNewBlobList->AddBlob(&NewBlob);
}
} /* Real size is known. */
else
{
CvSeq* cnt;
if(m_DetectedBlobs.GetBlobByID(i)) continue;
for(cnt=cnts; cnt; cnt=cnt->h_next)
{
//CvBlob* pNewBlob = NULL;
CvBlob NewBlob;
CvRect r = cvBoundingRect( cnt );
float x = RealPos.x - r.x;
float y = RealPos.y - r.y;
if(x<0 || x > r.width || y < 0 || y > r.height ) continue;
if( r.x <= 1 ||
r.y <= 1 ||
r.x + r.width >= pMask->width - 2 ||
r.y + r.height >= pMask->height - 2 ) continue;
/* Yes!! We found new blob, let's add it to list: */
NewBlob.x = RealPos.x;
NewBlob.y = RealPos.y;
NewBlob.w = (float)r.width;
NewBlob.h = (float)r.height;
NewBlob.ID = i;
m_DetectedBlobs.AddBlob(&NewBlob);
pNewBlobList->AddBlob(&NewBlob);
}
} /* Check new blob entrance. */
} /* Check next object. */
return pNewBlobList->GetBlobNum();
} /* cvDetectNewBlob */
void Release(){delete this;};
};
/* Blob detector constructor: */
CvBlobDetector* cvCreateBlobDetectorReal(CvTestSeq* pTestSeq){return new CvBlobDetectorReal(pTestSeq);}

View File

@@ -50,8 +50,14 @@
#endif
#include "opencv2/legacy/legacy.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/core/internal.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/legacy/blobtrack.hpp"
#include "opencv2/legacy/compat.hpp"
#include "_matrix.h"
typedef unsigned short ushort;

File diff suppressed because it is too large Load Diff