#opencv
#opencv
Вопрос:
Я нахожусь в процессе реализации алгоритма Lucas-Kanade с использованием OpenCV. Хотя мое намерение состоит в том, чтобы отслеживать черты лица, в качестве первого варианта я получаю все хорошие функции с помощью cvGoodFeatures api и использую эти точки в качестве входных данных, я пытаюсь отслеживать точки с помощью алгоритма Lucas-Kanade.
Теперь сценарий таков: если я начну перемещать объекты, снятые камерой, ближе к краям кадра (не за пределы кадра), я наблюдаю, что алгоритм LK начинает выдавать мне точки, которые либо находятся за пределами кадра, либо имеют отрицательные значения.
Пожалуйста, дайте мне знать, делаю ли я неправильную реализацию или такое поведение ожидается от метода отслеживания LK. Также я прилагаю свой код в конце этого поста для справки.
С уважением, Суджил Си
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 amp;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 amp;amp; ((currentFrameSize.width != cvGetSize(frame).width) || (currentFrameSize.height != cvGetSize(frame).height))))
{
// Release images
cvReleaseImage(amp;grey);
cvReleaseImage(amp;prev_grey);
cvReleaseImage(amp;pyramid);
cvReleaseImage(amp;prev_pyramid);
cvReleaseImage(amp;velx);
cvReleaseImage(amp;vely);
// Release buffers
cvFree(amp;(points[0]));
cvFree(amp;(points[1]));
cvFree(amp;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:%dn", 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], amp;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( amp;eig );
cvReleaseImage( amp;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];
}