如何使用opencv实现金字塔光流lk跟踪算法

星闻娱乐 2024-06-17 14:33:21
最佳回答
#include <stdio.h> #include <windows.h> #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <opencv2\opencv.hpp> using namespace cv; static const double pi = 3.14159265358979323846; inline static double square(int a) { return a * a; } /*该函数目的:给img分配内存空间,并设定format,如位深以及channel数*/ inline static void allocateondemand(iplimage **img, cvsize size, int depth, int channels) { if (*img != **) return; *img = cvcreateimage(size, depth, channels); if (*img == **) { fprintf(stderr, "error: couldn't allocate image. out of memory?\n"); exit(-1); } } /*主函数,原程序是读取**i视频文件,然后处理,我简单改成从摄像头直接读取数据*/ int main(int argc, char *argv[]) { //读取摄像头 videocapture cap(0); //读取视频文件 //videocapture cap; cap.open("optical_flow_input.**i"); if (!cap.**opened()) { return -1; } mat frame; /* bool stop = false; while (!stop) { cap >> frame; // cvtcolor(frame, edges, cv_rgb2gray); // gaussianblur(edges, edges, size(7, 7), 1.5, 1.5); // canny(edges, edges, 0, 30, 3); // imshow("当前视频", edges); imshow("当前视频", frame); if (waitkey(30) >= 0) stop = true; } */ //cvcapture *input_video = cvcapturefromfile( "optical_flow_input.**i" ); //cv::videocapture cap = *(cv::videocapture *) userdata; //if (input_video == **) // { // fprintf(stderr, "error: can't open video device.\n"); // return -1; // } /*先读取一帧,以便得到帧的属性,如长、宽等*/ //cvqueryframe(input_video); /*读取帧的属性*/ cvsize frame_size; frame_size.height = cap.get(cv_cap_prop_frame_height); frame_size.width = cap.get(cv_cap_prop_frame_width); /*********************************************************/ /*用于把结果写到文件中去,非必要 int framew = frame_size.height; // 744 for firewire cameras int frameh = frame_size.width; // 480 for firewire cameras videowriter writer("videotest.**i", -1, 25.0, cvsize(framew, frameh), true); /*开始光流法*/ //videowriter writer("videotest.**i", cv_fourcc('d', 'i', 'v', 'x'), 25.0, size(640, 480), true); while (true) { static iplimage *frame = **, *frame1 = **, *frame1_1c = **, *frame2_1c = **, *eig_image = **, *temp_image = **, *pyramid1 = **, *pyramid2 = **; mat framet; /*获取第一帧*/ // cap >> framet; cap.read(framet); mat edges; //黑白抽象滤镜模式 // cvtcolor(framet, edges, cv_rgb2gray); // gaussianblur(edges, edges, size(7, 7), 1.5, 1.5); // canny(edges, edges, 0, 30, 3); //转换mat格式到lpiimage格式 frame = &iplimage(framet); if (frame == **) { fprintf(stderr, "error: hmm. the end came sooner than we thought.\n"); return -1; } /*由于opencv的光流函数处理的是8位的灰度图,所以需要创建一个同样格式的 iplimage的对象*/ allocateondemand(&frame1_1c, frame_size, ipl_depth_8u, 1); /* 把摄像头图像格式转换成opencv惯常处理的图像格式*/ cvconvertimage(frame, frame1_1c, 0); /* 我们需要把具有全部颜色信息的原帧保存,以备最后在屏幕上显示用*/ allocateondemand(&frame1, frame_size, ipl_depth_8u, 3); cvconvertimage(frame, frame1, 0); /* 获取第二帧 */ //cap >> framet; cap.read(framet); // cvtcolor(framet, edges, cv_rgb2gray); // gaussianblur(edges, edges, size(7, 7), 1.5, 1.5); // canny(edges, edges, 0, 30, 3); frame = &iplimage(framet); if (frame == **) { fprintf(stderr, "error: hmm. the end came sooner than we thought.\n"); return -1; } /*原理同上*/ allocateondemand(&frame2_1c, frame_size, ipl_depth_8u, 1); cvconvertimage(frame, frame2_1c, 0); /********************************************************* 开始shi-tomasi算法,该算法主要用于feature selection,即一张图中哪些是我 们感兴趣需要跟踪的点(interest point) input: * "frame1_1c" 输入图像. * "eig_image" and "temp_image" 只是给该算法提供可操作的内存区域. * 第一个".01" 规定了特征值的最小质量,因为该算法要得到好的特征点,哪就 需要一个选择的阈值 * 第二个".01" 规定了像素之间最小的距离,用于减少运算复杂度,当然也一定 程度降低了跟踪精度 * "**" 意味着处理整张图片,当然你也可以指定一块区域 output: * "frame1_features" 将会包含fram1的特征值 * "number_of_features" 将在该函数中自动填充上所找到特征值的真实数目, 该值<= 400 **********************************************************/ /*开始准备该算法需要的输入*/ /* 给eig_image,temp_image分配空间*/ allocateondemand(&eig_image, frame_size, ipl_depth_32f, 1); allocateondemand(&temp_image, frame_size, ipl_depth_32f, 1); /* 定义存放frame1特征值的数组,400只是定义一个上限 */ cvpoint2d32f frame1_features[400]; int number_of_features = 400; /*开始跑shi-tomasi函数*/ cvgoodfeaturestotrack(frame1_1c, eig_image, temp_image, frame1_features, &number_of_features, .01, .01, **); /********************************************************** 开始金字塔lucas kanade光流法,该算法主要用于feature tracking,即是算出 光流,并跟踪目标。 input: * "frame1_1c" 输入图像,即8位灰色的第一帧 * "frame2_1c" 第二帧,我们要在其上找出第一帧我们发现的特征点在第二帧 的什么位置 * "pyramid1" and "pyramid2" 是提供给该算法可操作的内存区域,计算中间 数据 * "frame1_features" 由shi-tomasi算法得到的第一帧的特征点. * "number_of_features" 第一帧特征点的数目 * "optical_flow_termination_criteria" 该算法中迭代终止的判别,这里是 epsilon<0.3,epsilon是两帧中对应特征窗口的光度之差的平方,这个以后的文 章会讲 * "0" 这个我不知道啥意思,反正改成1就出不来光流了,就用作者原话解释把 means d**able enhancements. (for example, the second array **n't pre-initialized with guesses.) output: * "frame2_features" 根据第一帧的特征点,在第二帧上所找到的对应点 * "optical_flow_window" lucas-kanade光流算法的运算窗口,具体lucas-kanade 会在下一篇详述 * "5" 指示最大的金字塔层数,0表示只有一层,那就是没用金字塔算法 * "optical_flow_found_feature" 用于指示在第二帧中是否找到对应特征值, 若找到,其值为非零 * "optical_flow_feature_error" 用于存放光流误差 **********************************************************/ /*开始为pyramid lucas kanade光流算法输入做准备*/ cvpoint2d32f frame2_features[400]; /* 该数组相应位置的值为非零,如果frame1中的特征值在frame2中找到 */ char optical_flow_found_feature[400]; /* 数组第i个元素表对应点光流误差*/ float optical_flow_feature_error[400]; /*lucas-kanade光流法运算窗口,这里取3*3的窗口,可以尝试下5*5,区别就是5*5 出现aperture problem的几率较小,3*3运算量小,对于feature selection即shi-tomasi算法来说足够了*/ cvsize optical_flow_window = cvsize(5, 5); // cvsize optical_flow_window = cvsize(5, 5); /* 终止规则,当完成20次迭代或者当epsilon<=0.3,迭代终止,可以尝试下别的值*/ cvtermcriteria optical_flow_termination_criteria= cvtermcriteria(cv_termcrit_iter | cv_termcrit_eps, 20, .3); /*分配工作区域*/ allocateondemand(&pyramid1, frame_size, ipl_depth_8u, 1); allocateondemand(&pyramid2, frame_size, ipl_depth_8u, 1); /*开始跑该算法*/ cvcalcopticalflowpyrlk(frame1_1c, frame2_1c, pyramid1, pyramid2,frame1_features, frame2_features, number_of_features, optical_flow_window, 5, optical_flow_found_feature,optical_flow_feature_error, optical_flow_termination_criteria, 0); /*画光流场,画图是依据两帧对应的特征值, 这个特征值就是图像上我们感兴趣的点,如边缘上的点p(x,y)*/ for (int i = 0; i< number_of_features; i++) { /* 如果没找到对应特征点 */ if (optical_flow_found_feature[i] == 0) continue; int line_thickness; line_thickness = 1; /* cv_rgb(red, green, blue) ** the red, green, and blue components * of the color you want, each out of 255. */ cvscalar line_color; line_color = cv_rgb(255, 0, 0); /*画箭头,因为帧间的运动很小,所以需要缩放,不然看不见箭头,缩放因子为3*/ cvpoint p, q; p.x = (int)frame1_features[i].x; p.y = (int)frame1_features[i].y; q.x = (int)frame2_features[i].x; q.y = (int)frame2_features[i].y; double angle; angle = atan2((double)p.y - q.y, (double)p.x - q.x); double hypotenuse; hypotenuse = sqrt(square(p.y - q.y) + square(p.x - q.x)); /*执行缩放*/ q.x = (int)(p.x - 5 * hypotenuse * cos(angle)); q.y = (int)(p.y - 5 * hypotenuse * sin(angle)); /*画箭头主线*/ /* "frame1"要在frame1上作画. * "p" 线的开始点. * "q" 线的终止点. * "cv_aa" 反锯齿. * "0" 没有小数位. */ cvline(frame1, p, q, line_color, line_thickness, cv_aa, 0); /* 画箭的头部*/ p.x = (int)(q.x + 9 * cos(angle + pi / 4)); p.y = (int)(q.y + 9 * sin(angle + pi / 4)); cvline(frame1, p, q, line_color, line_thickness, cv_aa, 0); p.x = (int)(q.x + 9 * cos(angle - pi / 4)); p.y = (int)(q.y + 9 * sin(angle - pi / 4)); cvline(frame1, p, q, line_color, line_thickness, cv_aa, 0); } /*显示图像*/ /*创建一个名为optical flow的窗口,大小自动改变*/ cvnamedwindow("optical flow", cv_window_normal); cvflip(frame1, **, 2); cvshowimage("optical flow", frame1); /*延时,要不放不了*/ cvwaitkey(33); /*写入到文件中去*/ // cv::mat m = cv::cvarrtomat(frame1);//转换lpimgae到mat格式 // writer << m;//opencv3.0 version writer } cap.release(); cvwaitkey(33); system("pause"); } 20210311
汇率兑换计算器

类似问答
  • 国内如何购买跟踪msci指数的基金?
    • 2024-06-17 11:11:19
    • 提问者: 未知
    想要在资产配置中增加一部分跟踪msci发达市场指数和msci新兴市场指数的基金,在晨星网上没有找到国内跟踪…
  • 如何使用obv指标跟踪**是否进出货
    • 2024-06-17 11:42:59
    • 提问者: 未知
    obv指标又称为能量潮,也叫成交量净额指标。其计算公式为:当日obv=前一日obv+今日成交量。注:如果当日收盘价高于前日收盘价取正值,反之取负值,平盘取零。1、在证券市场中,价格、成交量、时间、空间是进行技术分析的四大要素,由此我们应该清楚obv指标作为成交量的指标,它不能单独使用,必须与价格曲线同时使用才能发挥作用。2、obv指标方向的选择反映了市场主流资金对持仓兴趣增减的变化。obv指标的曲...
  • 金字塔建仓方法
    • 2024-06-17 20:20:55
    • 提问者: 未知
    金字塔买入法则是全世界较为风行的建仓操作法之一,无论是欧美的投资**,还是一般的投资基金,都使用“金字塔”...850美元以下为低风险价值区域,价格越低风险系数越小,...
  • 对别人尾随跟踪有罪吗?算不算违**
    • 2024-06-17 01:54:44
    • 提问者: 未知
    在我国《刑法》中讲了关于尾随跟踪是否有罪的问题。《刑法》第二百三十七条强制**、侮辱妇女罪、**儿童罪是指以**、胁迫或者其他方法强制**妇女或者侮辱妇女的,处...
  • 如何跟踪库存周期?
    • 2024-06-17 08:11:55
    • 提问者: 未知
    此外还有一个ppi指标,ppi统计的是工业生产环节中的价格情况,大概覆盖了全国工业销售的70%,还是具有相当的代表性,历史数据来看ppi的同比走势与产成品的库存走势基本…差...
  • 期货中的金字塔购买法是否也使用股票?
    • 2024-06-17 03:15:07
    • 提问者: 未知
    倒金塔卖出法要求,当股票价位不断升高时,卖出的数量应效仿倒三角形的形状而逐渐扩大,以赚取更多的差价收益。...嗯,期货中技术分析的方法和股票基本上是通用的,但是有一点...
  • 如何追踪主力机构的资金流向?
    • 2024-06-17 11:22:33
    • 提问者: 未知
    如何追踪主力机构的资金流向?追踪主力资金,在股市上是一个永恒的话题!其中的难度之大,绝非几句话就可以在这里说清楚。即使是用一本书的篇幅,能将这个问题:-流向,追踪...
  • 被人跟踪,如何甩开?
    • 2024-06-17 22:27:36
    • 提问者: 未知
    说一个自己的故事。本人小语种留学生,去年除夕夜在同学家聚餐,回家已经是凌晨了,路上被一个**伯人跟…
  • 如何对股票全面跟踪?
    • 2024-06-17 01:09:23
    • 提问者: 未知
    全面跟踪?不太明白你说的意思,每天都盯盘,看这只股票的走势,挂单,成交量等等,慢慢找到**的操盘规律,你就可以在这只股票上做波段了。
  • 现金流量直接法如何计算
    • 2024-06-17 03:31:22
    • 提问者: 未知
    计算公式:销售商品、提供劳务收到的现金=本期营业收入净额+本期应收账款减少额(-应收账款增加额)+本期应收**减少额(-应收**增加额)+本期预收账款增加额(-预收账款减少额)  按规定,企业应当采用直接法,列示经营活动产生的现金流量。  直接法是按现金流入和现金流出的主要类别列示企业经营活动产生的现金流量。在直接法下,一般是以利润表中的营业收入为起算点,调整与经营活动有关的项目的增减变动,然后计...
汇率兑换计算器

热门推荐
热门问答
最新问答
推荐问答
新手帮助
常见问题
房贷计算器-九子财经 | 备案号: 桂ICP备19010581号-1 商务联系 企鹅:2790-680461

特别声明:本网为公益网站,人人都可发布,所有内容为会员自行上传发布",本站不承担任何法律责任,如内容有该作者著作权或违规内容,请联系我们清空删除。