OpenCV:金字塔Lucas-Kanade光流算法之函数接口cvCalcOpticalFlowPyrLK的使用

Lucas-Kanade光流算法的原理具体可以参考这篇博客:Lucas–Kanade(LK)光流算法详解

函数原型

void cvCalcOpticalFlowPyrLK( const CvArr* prev, const CvArr* curr, CvArr* prev_pyr, CvArr* curr_pyr,
                             const CvPoint2D32f* prev_features, CvPoint2D32f* curr_features,
                             int count, CvSize win_size, int level, char* status,
                             float* track_error, CvTermCriteria criteria, int flags );

参数

prev

在时间 t 的第一帧

curr

在时间 t + dt 的第二帧

prev_pyr

第一帧的金字塔缓存. 如果指针非 NULL , 则缓存必须有足够的空间来存储金字塔从层 1 到层 #level 的内容。尺寸 (image_width+8)*image_height/3 比特足够了

curr_pyr

与 prev_pyr 类似, 用于第二帧

prev_features

需要发现光流的点集

curr_features

包含新计算出来的位置的 点集

count

特征点的数目

win_size

每个金字塔层的搜索窗口尺寸

level

最大的金字塔层数。如果为 0 , 不使用金字塔 (即金字塔为单层), 如果为 1 , 使用两层,下面依次类推。

status

数组。如果对应特征的光流被发现,数组中的每一个元素都被设置为 1, 否则设置为 0。

error

双精度数组,包含原始图像碎片与移动点之间的差。为可选参数,可以是 NULL .

criteria

准则,指定在每个金字塔层,为某点寻找光流的迭代过程的终止条件。

flags

其它选项:

  • CV_LKFLOW_PYR_A_READY , 在调用之前,第一帧的金字塔已经准备好
  • CV_LKFLOW_PYR_B_READY , 在调用之前,第二帧的金字塔已经准备好
  • CV_LKFLOW_INITIAL_GUESSES , 在调用之前,数组 B 包含特征的初始坐标 (Hunnish: 在本节中没有出现数组 B,不知是指的哪一个)

函数 cvCalcOpticalFlowPyrLK 实现了金字塔中 Lucas-Kanade 光流计算的稀疏迭代版本 ([Bouguet00])。 它根据给出的前一帧特征点坐标计算当前视频帧上的特征点坐标。 函数寻找具有子象素精度的坐标值。

两个参数 prev_pyr 和 curr_pyr 都遵循下列规则: 如果图像指针为 0, 函数在内部为其分配缓存空间,计算金字塔,然后再处理过后释放缓存。 否则,函数计算金字塔且存储它到缓存中,除非设置标识 CV_LKFLOW_PYR_A[B]_READY 。 图像应该足够大以便能够容纳 Gaussian 金字塔数据。调用函数以后,金字塔被计算而且相应图像的标识可以被设置,为下一次调用准备就绪 (比如:对除了第一个图像的所有图像序列,标识 CV_LKFLOW_PYR_A_READY 被设置).

测试Demo(OpenCV示例代码)

#include 
#include 
#include 
#include 
 
const int MAX_CORNERS = 500;
int main(int argc, char** argv) {
 
    IplImage* imgA = cvLoadImage("OpticalFlow0.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    IplImage* imgB = cvLoadImage("OpticalFlow1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    CvSize      img_sz    = cvGetSize( imgA );
    int         win_size = 10;
    IplImage* imgC = cvLoadImage("OpticalFlow1.jpg",CV_LOAD_IMAGE_UNCHANGED);
 
    //需要做的第一件事就是获取我们想要跟踪的特征
    IplImage* eig_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
    IplImage* tmp_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
    int              corner_count = MAX_CORNERS;
    CvPoint2D32f* cornersA        = new CvPoint2D32f[ MAX_CORNERS ];
    cvGoodFeaturesToTrack(
        imgA,
        eig_image,
        tmp_image,
        cornersA,
        &corner_count,
        0.01,
        5.0,
        0,
        3,
        0,
        0.04
        );
    cvFindCornerSubPix(
        imgA,
        cornersA,
        corner_count,
        cvSize(win_size,win_size),
        cvSize(-1,-1),
        cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)
        );
 
    char features_found[ MAX_CORNERS ];
    float feature_errors[ MAX_CORNERS ];
    CvSize pyr_sz = cvSize( imgA->width+8, imgB->height/3 );
    IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
    IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
    CvPoint2D32f* cornersB        = new CvPoint2D32f[ MAX_CORNERS ];
    cvCalcOpticalFlowPyrLK(				//在图像金字塔中计算LK光流
        imgA,
        imgB,
        pyrA,
        pyrB,
        cornersA,
        cornersB,
        corner_count,
        cvSize( win_size,win_size ),
        5,
        features_found,
        feature_errors,
        cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ),
        0
        );
 
    for( int i=0; i550 ) {
            printf("Error is %f/n",feature_errors[i]);
            continue;
        }
        printf("Got it/n");
        CvPoint p0 = cvPoint(
            cvRound( cornersA[i].x ),
            cvRound( cornersA[i].y )
            );
        CvPoint p1 = cvPoint(
            cvRound( cornersB[i].x ),
            cvRound( cornersB[i].y )
            );
        cvLine( imgC, p0, p1, CV_RGB(255,0,0),2 );
    }
    cvNamedWindow("ImageA",0);
    cvNamedWindow("ImageB",0);
    cvNamedWindow("LKpyr_OpticalFlow",0);
    cvShowImage("ImageA",imgA);
    cvShowImage("ImageB",imgB);
    cvShowImage("LKpyr_OpticalFlow",imgC);
    cvWaitKey(0);
    return 0;
}

运行结果

OpenCV:金字塔Lucas-Kanade光流算法之函数接口cvCalcOpticalFlowPyrLK的使用_第1张图片

你可能感兴趣的:(图像处理,OpenCV)