我正在使用OpenCv实现Lucas-Kanade算法。即使我的目的是跟踪面部特征,作为第一个剪辑我使用cvGoodFeatures api获得所有好的功能并使用这些点作为输入,我试图使用Lucas-Kanade算法跟踪点。
现在的情况是,如果我开始移动相机捕获的对象靠近帧的边缘(不在帧外),我观察到的是LK算法开始给我在帧外或有负点的点值。
请让我知道我是在做错误的实现还是LK跟踪方法预期的这种行为。另外,我在本文末尾附上我的代码以供参考。
此致 Sujil C
IplImage *image = 0,
*grey = 0,
*prev_grey = 0,
*pyramid = 0,
*prev_pyramid = 0,
*swap_temp = 0,
*velx = 0,
*vely = 0;
const int MAX_COUNT = 20;
CvPoint2D32f* points[2] = {0,0}, *swap_points;
char* status = 0;
int lkcount = 0;
int detectGoodFeature = 0;
int flags = 0;
CvPoint pt;
CvSize currentFrameSize;
CvPoint2D32f* processLKFrame(IplImage* frame, int &pointCount)
{
int win_size = 15;
int level = 5;
int i, k;
// If frame size has changed, release all resources (they will be reallocated further on)
if ( (grey && ((currentFrameSize.width != cvGetSize(frame).width) || (currentFrameSize.height != cvGetSize(frame).height))))
{
// Release images
cvReleaseImage(&grey);
cvReleaseImage(&prev_grey);
cvReleaseImage(&pyramid);
cvReleaseImage(&prev_pyramid);
cvReleaseImage(&velx);
cvReleaseImage(&vely);
// Release buffers
cvFree(&(points[0]));
cvFree(&(points[1]));
cvFree(&status);
// Zerofiy grey so initialization will occur
grey = NULL;
}
// Initialize
if( !grey )
{
/* allocate all the buffers */
currentFrameSize = cvGetSize(frame);
grey = cvCreateImage( currentFrameSize, 8, 1 );
prev_grey = cvCreateImage( currentFrameSize, 8, 1 );
pyramid = cvCreateImage( currentFrameSize, 8, 1 );
prev_pyramid = cvCreateImage( currentFrameSize, 8, 1 );
velx = cvCreateImage(currentFrameSize, 32, 1);
vely = cvCreateImage(currentFrameSize, 32, 1);
points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0]));
status = (char*)cvAlloc(MAX_COUNT);
flags = 0;
}
printf("Current Frame Size : Width:%d Height:%d\n", currentFrameSize.width, currentFrameSize.height );
cvCopy( frame, grey, 0 );
if (detectGoodFeature) {
/* automatic initialization */
IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 );
IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 );
double quality = 0.01;
double min_distance = 10;
lkcount = MAX_COUNT;
cvGoodFeaturesToTrack( grey, eig, temp, points[1], &lkcount,
quality, min_distance, 0, 3, 0, 0.04 );
cvFindCornerSubPix( grey, points[1], lkcount,
cvSize(win_size,win_size), cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
cvReleaseImage( &eig );
cvReleaseImage( &temp );
}
else if( lkcount > 0 )
{
//For debugging points
printf("==============================================================================================================\n");
printf("Input Points:");
for (int i = 0; i < lkcount; i++) {
printf("(%f, %f)", points[0][i].x, points[0][i].y);
}
printf("\n");
// Calc movement of tracked points
cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid,
points[0], points[1], lkcount, cvSize(win_size,win_size), level, status, 0,
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), 0 );
//For debugging points
printf("Tracked Points:");
for (int i = 0; i < lkcount; i++) {
printf("(%f, %f),", points[1][i].x, points[1][i].y);
}
printf("\n");
printf("==============================================================================================================\n");
}
CV_SWAP( prev_grey, grey, swap_temp );
CV_SWAP( prev_pyramid, pyramid, swap_temp );
CV_SWAP( points[0], points[1], swap_points );
detectGoodFeature = 0;
pointCount = lkcount;
return points[0];
}