Отслеживание функций с помощью Lucas Kanade

#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];


}