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:
211
modules/legacy/src/bgfg_estimation.cpp
Normal file
211
modules/legacy/src/bgfg_estimation.cpp
Normal 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);
|
||||
}
|
640
modules/legacy/src/blobtrack.cpp
Normal file
640
modules/legacy/src/blobtrack.cpp
Normal 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;
|
||||
}
|
||||
|
128
modules/legacy/src/blobtrackanalysis.cpp
Normal file
128
modules/legacy/src/blobtrackanalysis.cpp
Normal 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 ============================= */
|
||||
|
1524
modules/legacy/src/blobtrackanalysishist.cpp
Normal file
1524
modules/legacy/src/blobtrackanalysishist.cpp
Normal file
File diff suppressed because it is too large
Load Diff
174
modules/legacy/src/blobtrackanalysisior.cpp
Normal file
174
modules/legacy/src/blobtrackanalysisior.cpp
Normal 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 ============================= */
|
||||
|
583
modules/legacy/src/blobtrackanalysistrackdist.cpp
Normal file
583
modules/legacy/src/blobtrackanalysistrackdist.cpp
Normal 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;}
|
||||
|
185
modules/legacy/src/blobtrackgen1.cpp
Normal file
185
modules/legacy/src/blobtrackgen1.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
219
modules/legacy/src/blobtrackgenyml.cpp
Normal file
219
modules/legacy/src/blobtrackgenyml.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
485
modules/legacy/src/blobtrackingauto.cpp
Normal file
485
modules/legacy/src/blobtrackingauto.cpp
Normal 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( <ime );
|
||||
char* stime = ctime( <ime );
|
||||
#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 */
|
||||
|
556
modules/legacy/src/blobtrackingcc.cpp
Normal file
556
modules/legacy/src/blobtrackingcc.cpp
Normal 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 =============== */
|
495
modules/legacy/src/blobtrackingccwithcr.cpp
Normal file
495
modules/legacy/src/blobtrackingccwithcr.cpp
Normal 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 =============== */
|
173
modules/legacy/src/blobtrackingkalman.cpp
Normal file
173
modules/legacy/src/blobtrackingkalman.cpp
Normal 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);
|
||||
}
|
548
modules/legacy/src/blobtrackinglist.cpp
Normal file
548
modules/legacy/src/blobtrackinglist.cpp
Normal 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);
|
||||
}
|
1184
modules/legacy/src/blobtrackingmsfg.cpp
Normal file
1184
modules/legacy/src/blobtrackingmsfg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
457
modules/legacy/src/blobtrackingmsfgs.cpp
Normal file
457
modules/legacy/src/blobtrackingmsfgs.cpp
Normal 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);
|
||||
}
|
||||
|
327
modules/legacy/src/blobtrackpostprockalman.cpp
Normal file
327
modules/legacy/src/blobtrackpostprockalman.cpp
Normal 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 =========================*/
|
||||
|
128
modules/legacy/src/blobtrackpostproclinear.cpp
Normal file
128
modules/legacy/src/blobtrackpostproclinear.cpp
Normal 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 =========================*/
|
133
modules/legacy/src/blobtrackpostproclist.cpp
Normal file
133
modules/legacy/src/blobtrackpostproclist.cpp
Normal 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 =====================*/
|
684
modules/legacy/src/compat.cpp
Normal file
684
modules/legacy/src/compat.cpp
Normal 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 );
|
||||
}
|
1064
modules/legacy/src/enteringblobdetection.cpp
Normal file
1064
modules/legacy/src/enteringblobdetection.cpp
Normal file
File diff suppressed because it is too large
Load Diff
168
modules/legacy/src/enteringblobdetectionreal.cpp
Normal file
168
modules/legacy/src/enteringblobdetectionreal.cpp
Normal 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);}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
|
1374
modules/legacy/src/testseq.cpp
Normal file
1374
modules/legacy/src/testseq.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user