OpenCV中CalcOpticalFlowFarneback()函数分析
来源:互联网 发布:sqlserver打开数据库 编辑:程序博客网 时间:2024/05/21 17:12
OpenCV中CalcOpticalFlowFarneback函数
函数简介
CalcOpticalFlowFarneback()函数是利用用Gunnar Farneback的算法计算全局性的稠密光流算法(即图像上所有像素点的光流都计算出来),由于要计算图像上所有点的光流,故计算耗时,速度慢。它的核心思想主要源于”Two-Frame Motion Estimation Based on PolynomialExpansion”论文。下面是是对此函数的详细介绍。
函数分析
void cv::calcOpticalFlowFarneback( InputArray _prev0, InputArray _next0, OutputArray _flow0, double pyr_scale, int levels, int winsize, int iterations, int poly_n, double poly_sigma, int flags )// 参数说明如下:// _prev0:输入前一帧图像// _next0:输入后一帧图像// _flow0:输出的光流// pyr_scale:金字塔上下两层之间的尺度关系// levels:金字塔层数// winsize:均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域// iterations:迭代次数// poly_n:像素领域大小,一般为5,7等// poly_sigma:高斯标注差,一般为1-1.5// flags:计算方法。主要包括OPTFLOW_USE_INITIAL_FLOW和OPTFLOW_FARNEBACK_GAUSSIAN// OpenCV中此函数源码void cv::calcOpticalFlowFarneback( InputArray _prev0, InputArray _next0, InputOutputArray _flow0, double pyr_scale, int levels, int winsize, int iterations, int poly_n, double poly_sigma, int flags ){#ifdef HAVE_OPENCL bool use_opencl = ocl::useOpenCL() && _flow0.isUMat(); if( use_opencl && ocl_calcOpticalFlowFarneback(_prev0, _next0, _flow0, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags)) { CV_IMPL_ADD(CV_IMPL_OCL); return; }#endif // 将_prev0和_next0转换为Mat类型 Mat prev0 = _prev0.getMat(), next0 = _next0.getMat(); const int min_size = 32; // 创建img指针数组,img[0]指向prev0,img[1]指向next0 const Mat* img[2] = { &prev0, &next0 }; int i, k; double scale; Mat prevFlow, flow, fimg; // 检查prev0和next0是否大小相同、单通道图像,金字塔尺度关系pyr_scale小于1 CV_Assert( prev0.size() == next0.size() && prev0.channels() == next0.channels() && prev0.channels() == 1 && pyr_scale < 1 ); // 创建和prev0大小相同,32位浮点双通道图像 _flow0.create( prev0.size(), CV_32FC2 ); // 将_flow0转换成Mat类型 Mat flow0 = _flow0.getMat(); // 循环确定金字塔层数 for( k = 0, scale = 1; k < levels; k++ ) { // scale用于存放第k层图像与原图的尺寸广西 scale *= pyr_scale; // 判断第k层图像行数与min_size关系,确定金字塔层数结束 if( prev0.cols*scale < min_size || prev0.rows*scale < min_size ) break; } // 将计算出的金字塔层数k赋给levels levels = k; // 遍历金字塔层数 for( k = levels; k >= 0; k-- ) { // 计算原图与k-1层图像的尺寸关系 for( i = 0, scale = 1; i < k; i++ ) scale *= pyr_scale; // 定义高斯滤波系数 double sigma = (1./scale-1)*0.5; int smooth_sz = cvRound(sigma*5)|1; // 得到高斯滤波器模板大小 smooth_sz = std::max(smooth_sz, 3); // 计算第k层图像矩阵的列数 int width = cvRound(prev0.cols*scale); // 计算第k层图像矩阵的行数 int height = cvRound(prev0.rows*scale); if( k > 0 ) // 创建第k层图像尺寸大小的32位双通道图像,用于存储第k层图像光流flow flow.create( height, width, CV_32FC2 ); else // 否则为原图像 flow = flow0; // 如果preFlow未指向任何矩阵数据 if( prevFlow.empty() ) { // 如果flags为OPTFLOW_USE_INITIAL_FLOW if( flags & OPTFLOW_USE_INITIAL_FLOW ) { // 改变flow0图像大小为flow,用像素关系重采样插值 // 插值使用錓NTER_AREA,主要是为了避免波纹出现 resize( flow0, flow, Size(width, height), 0, 0, INTER_AREA ); // 将flow缩小scale flow *= scale; } // flags为OPTFLOW_FARNEBACK_GAUSSIAN else // 创建一个Mat给flow flow = Mat::zeros( height, width, CV_32FC2 ); } else { // 改变prevFlow图像大小为flow,利用INTER_LINEAR方式进行双线性插值 resize( prevFlow, flow, Size(width, height), 0, 0, INTER_LINEAR ); // 将flow增加(1./pyr_sacle)倍 flow *= 1./pyr_scale; } Mat R[2], I, M; for( i = 0; i < 2; i++ ) { // 将img[i]转换为CV_32F格式 img[i]->convertTo(fimg, CV_32F); // 对输出图像fimg进行高斯滤波后用fimg输出 GaussianBlur(fimg, fimg, Size(smooth_sz, smooth_sz), sigma, sigma); // 改变fimg图像大小I,使用双线性插值INTER_LINEAR resize( fimg, I, Size(width, height), INTER_LINEAR ); // 计算邻域图像R[i] FarnebackPolyExp( I, R[i], poly_n, poly_sigma ); } // 依据R[0]、R[1]、flow等信息更新矩阵M FarnebackUpdateMatrices( R[0], R[1], flow, M, 0, flow.rows ); for( i = 0; i < iterations; i++ ) { // flags为OPTFLOW_FARNEBACK_GAUSSIAN if( flags & OPTFLOW_FARNEBACK_GAUSSIAN ) // 利用R[0]、R[1]、M等,利用高斯平滑原理,更新光流flow FarnebackUpdateFlow_GaussianBlur( R[0], R[1], flow, M, winsize, i < iterations - 1 ); // flags为OPTFLOW_USE_INITIAL_FLOW else // 利用R[0]、R[1]、M等初始化光流flow FarnebackUpdateFlow_Blur( R[0], R[1], flow, M, winsize, i < iterations - 1 ); } // 将flow赋给prevFlow prevFlow = flow; }}
参考文献:
http://www.chinadmd.com/file/poeootxpoprwtxpcwzw6awiu_1.html
http://www.aichengxu.com/view/2450131
http://blog.csdn.net/zouxy09/article/details/8683859
0 0
- OpenCV中CalcOpticalFlowFarneback()函数分析
- OpenCV中CalcOpticalFlowFarneback()函数分析
- OpenCV图像处理-光流法-原理分析1-calcOpticalFlowFarneback
- OpenCV Python calcOpticalFlowFarneback
- calcOpticalFlowFarneback函数解释
- calcOpticalFlowFarneback
- calcOpticalFlowFarneback
- openCV中cvSnakeImage()函数代码分析
- Farneback 光流算法详解与 calcOpticalFlowFarneback 源码分析
- OpenCV中cvFindContours函数
- opencv中CvvImage函数
- Opencv中cvSmooth函数
- OpenCV中GPU函数
- OpenCV中cvFindContours函数
- OpenCV中cvFindContours函数
- OpenCV中常用函数
- OpenCV中imread函数
- opencv中函数
- android里面R文件突然找不到,或者报错情况分析
- 【操作系统】概念总结
- Spring连载(1)
- 神经网络向量化
- Java笔记--CenOS6.5搭建hadoop2.7.1伪分布式环境
- OpenCV中CalcOpticalFlowFarneback()函数分析
- “水仙花”数的问题
- mybatis入门到精通教程
- hdu 1576 A/B (求乘法逆元——扩展欧几里得)
- 十大编程算法助程序员走上大神路
- dSYM文件解析与分析
- Android Intent传值
- iOS——界面通信
- kubernetes源码分析 -- kubelet组件