#include "_cvaux.h"
static float CalcAverageMask(CvBlob* pBlob, IplImage* pImgFG )
-{/* calc summ of mask */
+{ /* Calculate sum of mask: */
double Area, Aver = 0;
CvRect r;
CvMat mat;
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;
Aver = Sum/Area;
}
return (float)Aver;
-}/* calc summ of mask */
+} /* Calculate sum of mask. */
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */
int Collision;
CvBlobSeq* pBlobHyp;
float AverFG;
-}DefBlobTracker;
+} DefBlobTracker;
+
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage);
class CvBlobTrackerCC : public CvBlobTracker
char* m_ConfidenceTypeStr;
CvBlobSeq m_BlobList;
CvBlobSeq m_BlobListNew;
-// int m_LastID;
+// int m_LastID;
CvMemStorage* m_pMem;
int m_ClearHyp;
IplImage* m_pImg;
public:
CvBlobTrackerCC():m_BlobList(sizeof(DefBlobTracker))
{
-// m_LastID = 0;
+// 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");
+ CommentParam("Collision", "If 1 then collision cases are processed in special way");
m_AlphaSize = 0.02f;
AddParam("AlphaSize",&m_AlphaSize);
m_AlphaPos = 1.0f;
AddParam("AlphaPos",&m_AlphaPos);
- CommentParam("AlphaPos", "Pos update speed (0..1)");
+ CommentParam("AlphaPos", "Position update speed (0..1)");
m_Alpha = 0.001f;
AddParam("Alpha", &m_Alpha);
- CommentParam("Alpha","Coefficient for model histogramm updating (0 - hist is not upated)");
+ CommentParam("Alpha","Coefficient for model histogram updating (0 - hist is not updated)");
m_ConfidenceType=0;
m_ConfidenceTypeStr = "NearestBlob";
SetModuleName("CC");
};
+
~CvBlobTrackerCC()
{
if(m_pMem)cvReleaseMemStorage(&m_pMem);
};
- /* blob functions*/
+ /* 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)
{
/* return pointer to new added blob */
virtual CvBlob* AddBlob(CvBlob* pB, IplImage* /*pImg*/, IplImage* pImgFG = NULL )
{
- assert(pImgFG); /* this tracker use only foreground mask */
+ 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 predict position */
+ 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;
if(m_BlobList.GetBlobNum() <= 0 ) return;
- /* clear blob list for new blobs */
+ /* Clear bloblist for new blobs: */
m_BlobListNew.Clear();
assert(m_pMem);
assert(pImgFG);
- /* find CC */
+ /* Find CC: */
#if 0
- {// by contur clastring
+ { // By contour clustering:
cvFindBlobsByCCClasters(pImgFG, &m_BlobListNew, m_pMem);
}
#else
- {/* one contour - one blob */
+ { /* 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 contours*/
- for(cnt = cnts;cnt;cnt=cnt->h_next)
+
+ /* Process each contour: */
+ for(cnt = cnts; cnt; cnt=cnt->h_next)
{
CvBlob NewBlob;
- /* image moments */
+
+ /* Image moments: */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
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 */
+ } /* Next contour. */
+
cvReleaseImage(&pBin);
}
#endif
- for(i=m_BlobList.GetBlobNum();i>0;--i)
- {/* predict new blob position */
+ 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 previouse value of blob*/
+ /* Update predictor by previous value of blob: */
pBT->pPredictor->Update(&(pBT->blob));
- /* predict current position */
+ /* Predict current position: */
pB = pBT->pPredictor->Predict();
if(pB)
{
pBT->BlobPredict = pBT->blob;
}
- }/* predict new blob position */
+ } /* Predict new blob position. */
if(m_Collision)
- for(i=m_BlobList.GetBlobNum();i>0;--i)
- {/* predict 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 */
+
+ 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*/
+
+ } /* Check next blob to cross current. */
+
pF->Collision = Collision;
- }/* predict collision */
- for(i=m_BlobList.GetBlobNum();i>0;--i)
- {/* find a neighbour on cur frame for each blob from prev frame */
+ } /* 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);
//int j;
if(pBT->pBlobHyp->GetBlobNum()>0)
- {/* track all hypothesis */
+ { /* Track all hypotheses: */
int h,hN = pBT->pBlobHyp->GetBlobNum();
- for(h=0;h<hN;++h)
+ 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 */
+ 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));
DistBest = Dist;
pBBest = pBNew;
}
- }/* find best CC */
+ } /* Find best CC. */
+
if(pBBest)
{
pB[0] = pBBest[0];
CV_BLOB_ID(pB) = BlobID;
}
else
- { /* delete this hypothesis */
+ { /* Delete this hypothesis. */
pBT->pBlobHyp->DelBlob(h);
h--;
hN--;
}
- }/* next hyp*/
- }/* track all hypothesis */
- }/* track next blob */
+ } /* Next hypothysis. */
+ } /* Track all hypotheses. */
+ } /* Track next blob. */
m_ClearHyp = 1;
- }/* Process */
+ } /* Process. */
virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
BlobID = pB->ID;
if(m_Collision && pBT->Collision)
- {/* tracking in collision */
+ { /* Tracking in collision: */
pB[0]=pBT->BlobPredict;
CV_BLOB_ID(pB)=BlobID;
- }/* tracking in collision */
+ } /* Tracking in collision. */
else
- {/* not collision tracking */
+ { /* Non-collision tracking: */
CvBlob* pBBest = GetNearestBlob(pB);
if(pBBest)
{
pB->y = y;
CV_BLOB_ID(pB) = BlobID;
}
- }/* not collision tracking */
+ } /* Non-collision tracking. */
pBlob[0] = pB[0];
pBlob->ID = ID;
virtual double GetConfidence(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* pImgFG = NULL)
{
- /* define koefficients in exp by exp(-XT*K)=VT */
+ /* 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);
ds2 = dw*dw+dh*dh;
if(!pBT->Collision)
- { /* Confidence for size by nearest blob */
+ { /* Confidence for size by nearest blob: */
W*=exp(-_KS*ds2);
}
if(m_ConfidenceType==0 && !pBT->Collision)
- { /* confinence by nearest blob */
+ { /* Confidence by nearest blob: */
W*=exp(-_KP*dp2);
}
if(m_ConfidenceType==1 && pBT->AverFG>0)
- {/* calc summ of mask */
+ { /* Calculate sum of mask: */
float Aver = CalcAverageMask(pBlob, pImgFG );
if(Aver < pBT->AverFG)
{
if(diff < 0.1f) diff = 0.1f;
W *= diff;
}
- }/* calc summ of mask */
+ } /* Calculate sum of mask. */
if(m_ConfidenceType==2)
- {/* calc BCoeff */
+ { /* 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));
- }/* calc summ of mask */
+ } /* Calculate sum of mask. */
+
return W;
};
CvBlobTracker::ParamUpdate();
- for(i=0;i<3;++i)
+ for(i=0; i<3; ++i)
{
if(cv_stricmp(m_ConfidenceTypeStr,pCT[i])==0)
{
}
SetParamStr("ConfidenceType",pCT[m_ConfidenceType]);
}
- /* =============== MULTI HYPOTHESIS INTERFACE ================== */
- /* return number of position hyposetis of currently tracked blob */
+
+ /* =============== 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() */
+ }; /* CvBlobtrackerList::GetBlobHypNum() */
- /* return pointer to specified blob hypothesis by index blob */
+ /* 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 hyp (can be called several times for each hyp )*/
+ }; /* 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 hypothesis */
+ { /* Clear all hypotheses: */
int b, bN = m_BlobList.GetBlobNum();
- for(b=0;b<bN;++b)
+ for(b=0; b<bN; ++b)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(b);
assert(pBT->pBlobHyp);
}
m_ClearHyp = 0;
}
- {/* add hypothesis */
+ { /* Add hypothesis: */
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
assert(pBT->pBlobHyp);
pBT->pBlobHyp->AddBlob(pBlob);
BlobID = pB->ID;
- for(j=m_BlobListNew.GetBlobNum();j>0;--j)
- {/* find best CC */
+ 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));
DistBest = Dist;
pBBest = pBNew;
}
- }/* find best CC */
+
+ } /* Find best CC. */
+
return pBBest;
+
}; /* GetNearestBlob */
};