早就读了Zdenek Kalal的两篇经典文章,理解了tld及其中值流跟踪方法。
最近的项目中要实现动平台对静止目标跟踪。用相关系数做漂移有点大。于是想到了中值流方法。kalal公布的算法为matlab版本,但是其中的跟踪部分是用c写的。移植过来非常方便。
下面是移植后的跟踪函数
BOOL CTargetTrack::TrackMedianFlow(IplImage *pCurrentImage, CvPoint2D32f *point2, CvPoint2D32f *pointGuess)
{
int i, Level=5;;
int I = 0;
int J = 1;
int NCC_Winsize = 10;
float medncc,medfb,errXsum,errYsum,cnt;
IMG[I]= m_pLastImage;
IMG[J]= pCurrentImage;
PYR[I]= cvCreateImage( cvGetSize(pCurrentImage), 8, 1 );
PYR[J]= cvCreateImage( cvGetSize(pCurrentImage), 8, 1 );
bb_points(m_LastPoint,bbpts);
CvPoint2D32f pG;
if (pointGuess==NULL)
pG=m_LastPoint;
else
pG=*pointGuess;
bb_points(pG, bbptsGuess);
for (i = 0; i < nPts; i++)
{
points[0][i].x = bbpts[2*i]; points[0][i].y = bbpts[2*i+1];
points[1][i].x = bbptsGuess[2*i]; points[1][i].y = bbptsGuess[2*i+1];
points[2][i].x = bbpts[2*i]; points[2][i].y = bbpts[2*i+1];
}
cvCalcOpticalFlowPyrLK( IMG[I], IMG[J], PYR[I], PYR[J], points[0], points[1], nPts, cvSize(win_size,win_size), Level, status, 0, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), CV_LKFLOW_INITIAL_GUESSES);
cvCalcOpticalFlowPyrLK( IMG[J], IMG[I], PYR[J], PYR[I], points[1], points[2], nPts, cvSize(win_size,win_size), Level, 0 , 0, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), CV_LKFLOW_INITIAL_GUESSES | CV_LKFLOW_PYR_A_READY | CV_LKFLOW_PYR_B_READY );
normCrossCorrelation(IMG[I],IMG[J],points[0],points[1],nPts, status, ncc, NCC_Winsize,CV_TM_CCOEFF_NORMED);
euclideanDistance( points[0],points[2],fb,nPts);
memcpy(sort_ncc,ncc,nPts*sizeof(float));
memcpy(sort_fb, fb, nPts*sizeof(float));
quickSort(sort_ncc,0,nPts-1) ;
quickSort(sort_fb,0,nPts-1) ;
//float a1[121],a2[121],a3[121],a4[121];
//memcpy(a1,ncc,nPts*sizeof(float));
//memcpy(a2,sort_ncc,nPts*sizeof(float));
//memcpy(a3,fb,nPts*sizeof(float));
//memcpy(a4,sort_fb,nPts*sizeof(float));
medncc= sort_ncc[nPts/2];
medfb = sort_fb [nPts/2];
errXsum=0;
errYsum=0;
cnt= 0;
for (i=0;imedncc && fb[i]x= m_LastPoint.x+errXsum;
point2->y= m_LastPoint.y+errYsum;
// 计算相关系数,大于0.9则更新
IplImage *rec0 = cvCreateImage( cvSize(21, 21), 8, 1 );
IplImage *rec1 = cvCreateImage( cvSize(21, 21), 8, 1 );
IplImage *res = cvCreateImage( cvSize( 1, 1 ), IPL_DEPTH_32F, 1 );
cvGetRectSubPix( IMG[I], rec0, m_LastPoint );
cvGetRectSubPix( IMG[J], rec1, *point2 );
cvMatchTemplate( rec0,rec1, res, CV_TM_CCOEFF_NORMED );
if (*(float *)(res->imageData)>0.9)
{
Initiate(pCurrentImage, *point2);
}
cvReleaseImage( &rec0 );
cvReleaseImage( &rec1 );
cvReleaseImage( &res );
cvReleaseImage(&PYR[I]);
cvReleaseImage(&PYR[J]);
return (assertBorder(int(point2->x+0.5),m_nSearchR,pCurrentImage->width-m_nSearchR)&&
assertBorder(int(point2->y+0.5),m_nSearchR,pCurrentImage->height-m_nSearchR));
}
本文详细介绍了如何通过移植Zdenek Kalal的MATLAB算法并使用C语言实现中值流跟踪方法,应用于动平台对静止目标的实时跟踪。文中特别关注了相关系数在漂移控制上的不足,并提出了中值流方法作为替代方案,以减少误报率。通过实例展示,该方法在实际应用中展现出较高的稳定性和准确性。
117

被折叠的 条评论
为什么被折叠?



