您的位置:首页 > 运维架构

Optical_Flow(5)

2017-05-23 14:25 204 查看
//Pyramid L-K Optical Flow example//#include <opencv\highgui.h>  #include <opencv\cv.h>  #include <stdio.h>

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);

//The first thing we need to do is get the features we want to track 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(             //Call Lucate Kanade algorithmimgA,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; i<corner_count; i++) {if (features_found[i] == 0 || feature_errors[i]>550) {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;}




代码中用到的几个函数

1)cvGoodFeaturesToTrack 确定图像的强角点

void cvGoodFeaturesToTrack(

const CvArr* image //(8,1) or (32,1) (8-bit ,single-channel) (floating-point 32-bit,single-channel)

CvArr* eigImage,//(32,1)

CvArr* tempImage //(32,1)

CvPoint2D32f* corners

int* cornerCount

double qualityLevel

double minDistance

const CvArr* mask=NULL

int blockSize=3

int useHarris=0

double k=0.04 );

参数解析:

image:输入图像,8-位或浮点32-比特,单通道

eig_image:临时浮点32-位图像,尺寸与输入图像一致

temp_image:另外一个临时图像,格式与尺寸与 eig_image 一致

corners:输出参数,检测到的角点

corner_count:输出参数,检测到的角点数目

quality_level:最大最小特征值的乘法因子。定义可接受图像角点的最小质量因子。

min_distance:限制因子。得到的角点的最小距离。使用 Euclidian 距离

mask:ROI:感兴趣区域。函数在ROI中计算角点,如果 mask 为 NULL,则选择整个图像

该函数 cvGoodFeaturesToTrack 在图像中寻找具有大特征值的角点。首先用cvCornerMinEigenVal 计算输入图像的每一个像素点的最小特征值,并将结果存储到变量 eig_image 中。然后进行非最大值抑制(仅保留3x3邻域中的局部最大值)。下一步将最小特征值小于 quality_level?max(eig_image(x,y)) 排除掉。最后,函数确保所有发现的角点之间具有足够的距离,(最强的角点第一个保留,然后检查新的角点与已有角点之间的距离大于 min_distance )。

2)cvFindCornerSubPix 用于发现亚像素精度的角点位置

void cvFindCornerSubPix(

const CvArr* image,

CvPoint2D32f* corners,

int count,

CvSize win,

CvSize zero_zone,

CvTermCriteria criteria

);

输入图像image是8位通道的灰度图像。corners为整数值的像素位置,corners设定了角点的初始位置。count为需要计算的角点数目。win指定了等式产生的窗口的尺寸。输入参数zero_zone定义了一个禁区(与win相似,但通常比win小),这个区域在方程组以及自相关矩阵中不被考虑。如果不需要这样一个禁区,则zero_zone应设置为cvSize(-1,-1)。最后一个参数为用户定义的迭代终止条件。迭代过程的终止条件可以是最大迭代次数CV_TERMCRIT_ITER类型,或者是设定的精度CV_TERMCRIT_EPS类型(或者是两者的组合)。终止条件的设置在极大程度上影响最终得到的亚像素值的精度。例如,指定0.10,则求得的亚像素级精度为像素的十分之一。

3)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 包含特征的初始坐标
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: