OpenCV稠密光流估计的一个类cv::optflow::DenseRLOFOpticalFlow
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
cv::optflow::DenseRLOFOpticalFlow 是OpenCV 中用于稠密光流估计的一个类,属于optflow模块。它是RLOF(Regularized Location-Only Flow)算法的一种实现,用于计算视频帧之间的像素级运动矢量。
DenseRLOFOpticalFlow 是一种基于稀疏特征匹配 + 插值的稠密光流算法,其主要特点包括:
- 基于稀疏特征点(如 FAST、ORB)进行初始匹配;
- 使用正则化插值方法将稀疏匹配扩展为全图像素级别的光流场(稠密光流);
- 可以处理大位移运动(相比传统 LK 光流更鲁棒);
- 支持自定义特征检测器和描述子;
- 适用于视频稳定、动作分析、视频插值等任务。
常用静态方法
1.创建函数
static Ptr<DenseRLOFOpticalFlow> cv::optflow::DenseRLOFOpticalFlow::create
( Ptr< RLOFOpticalFlowParameter > rlofParam = Ptr< RLOFOpticalFlowParameter >(),float forwardBackwardThreshold = 1.f,Size gridStep = Size(6, 6),InterpolationType interp_type = InterpolationType::INTERP_EPIC,int epicK = 128,float epicSigma = 0.05f,float epicLambda = 999.0f,int ricSPSize = 15,int ricSLICType = 100,bool use_post_proc = true,float fgsLambda = 500.0f,float fgsSigma = 1.5f,bool use_variational_refinement = false )
参数:
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
rlofParam | Ptr | nullptr | 可选:自定义参数对象。如果传入,则其他参数将被忽略。 |
forwardBackwardThreshold | float | 1.0f | 正向/反向一致性检查的阈值。用于剔除不一致的匹配点。值越大越宽松。 |
gridStep | Size | (6, 6) | 稠密插值时使用的网格步长。值越小,插值越密集,计算量越大。 |
interp_type | InterpolationType | InterpolationType::INTERP_EPIC | 插值类型,可选:INTERP_LINEAR, INTERP_EPIC, INTERP_RIC |
epicK | int | 128 | EPIC 插值中使用的邻域大小。控制局部特征的范围。 |
epicSigma | float | 0.05f | EPIC 中高斯核的标准差,影响平滑程度。 |
epicLambda | float | 999.0f | EPIC 中正则化系数,防止过拟合。值越大越平滑。 |
ricSPSize | int | 15 | RIC 插值中的超像素大小。仅在使用 INTERP_RIC 时有效。 |
ricSLICType | int | 100 | SLIC 超像素分割类型。仅在使用 INTERP_RIC 时有效。 |
use_post_proc | bool | true | 是否启用后处理步骤(如去噪、平滑)。 |
fgsLambda | float | 500.0f | FGS 后处理中的正则化系数。控制平滑强度。 |
fgsSigma | float | 1.5f | FGS 后处理中的高斯核标准差。 |
use_variational_refinement | bool | false | 是否使用变分优化进一步提升精度(会显著增加计算时间)。 |
- calc(InputArray I0, InputArray I1, OutputArray flow) 计算从 I0 到 I1 的光流
- setFeatureDetector(Ptr detector) 设置自定义特征检测器
- setFeaturesToTrack(int numFeatures) 设置每帧中最多使用的特征点数
代码示例
#include <opencv2/opencv.hpp>
#include <opencv2/optflow/rlofflow.hpp>using namespace cv;
using namespace std;
// 将光流向量转换为 HSV 图像以便可视化
Mat visualizeFlow( const Mat& flow )
{vector< Mat > planes; // ✅ 正确声明 planes 为 vector<Mat>split( flow, planes ); // 自动拆分为两个通道:x-flow 和 y-flowMat mag, angle;cartToPolar( planes[ 0 ], planes[ 1 ], mag, angle, true ); // 计算幅度和角度normalize( mag, mag, 0, 1, NORM_MINMAX ); // 归一化到 [0, 1]// HSV 颜色空间可视化Mat hsv[ 3 ];hsv[ 0 ] = angle; // Hue = 方向hsv[ 1 ] = Mat::ones( angle.size(), CV_32F ); // Saturation = 1hsv[ 2 ] = mag; // Value = 幅度Mat hsvFull;merge( hsv, 3, hsvFull ); // 合并三个通道hsvFull.convertTo( hsvFull, CV_8U, 255.0 ); // 转换为 8U 类型用于显示Mat rgbOut;cvtColor( hsvFull, rgbOut, COLOR_HSV2BGR ); // 转换为 BGR 显示图像return rgbOut;
}
int main()
{// 读取两帧图像(灰度图)Mat frame1 = imread( "/media/dingxin/data/study/OpenCV/sources/images/left01.jpg", IMREAD_COLOR );Mat frame2 = imread( "/media/dingxin/data/study/OpenCV/sources/images/right01.jpg", IMREAD_COLOR );if ( frame1.empty() || frame2.empty() ){cerr << "无法加载图像!" << endl;return -1;}// 创建 DenseRLOF 实例并设置高级参数Ptr< optflow::DenseRLOFOpticalFlow > rlof = optflow::DenseRLOFOpticalFlow::create( nullptr, // 使用默认参数对象1.0f, // forwardBackwardThresholdSize( 8, 8 ), // gridStepoptflow::INTERP_EPIC, // interp_type128, // epicK0.05f, // epicSigma1000.0f, // epicLambda15, // ricSPSize100, // ricSLICTypetrue, // use_post_proc500.0f, // fgsLambda1.5f, // fgsSigmafalse // use_variational_refinement);// 计算稠密光流Mat flow;rlof->calc( frame1, frame2, flow );// 可视化结果Mat flowImage = visualizeFlow( flow );imshow( "Frame 1", frame1 );imshow( "Frame 2", frame2 );imshow( "Dense RLOF Optical Flow", flowImage );waitKey( 0 );return 0;
}