详细介绍: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
    )

参数:

参数名类型默认值说明
rlofParamPtrnullptr可选:自定义参数对象。如果传入,则其他参数将被忽略。
forwardBackwardThresholdfloat1.0f正向/反向一致性检查的阈值。用于剔除不一致的匹配点。值越大越宽松。
gridStepSize(6, 6)稠密插值时使用的网格步长。值越小,插值越密集,计算量越大。
interp_typeInterpolationTypeInterpolationType::INTERP_EPIC插值类型,可选:INTERP_LINEAR, INTERP_EPIC, INTERP_RIC
epicKint128EPIC 插值中使用的邻域大小。控制局部特征的范围。
epicSigmafloat0.05fEPIC 中高斯核的标准差,影响平滑程度。
epicLambdafloat999.0fEPIC 中正则化系数,防止过拟合。值越大越平滑。
ricSPSizeint15RIC 插值中的超像素大小。仅在使用 INTERP_RIC 时有效。
ricSLICTypeint100SLIC 超像素分割类型。仅在使用 INTERP_RIC 时有效。
use_post_procbooltrue是否启用后处理步骤(如去噪、平滑)。
fgsLambdafloat500.0fFGS 后处理中的正则化系数。控制平滑强度。
fgsSigmafloat1.5fFGS 后处理中的高斯核标准差。
use_variational_refinementboolfalse是否使用变分优化进一步提升精度(会显著增加计算时间)。
  1. calc(InputArray I0, InputArray I1, OutputArray flow) 计算从 I0 到 I1 的光流
  2. setFeatureDetector(Ptr detector) 设置自定义特征检测器
  3. 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-flow
        Mat 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 = 1
        hsv[ 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, // forwardBackwardThreshold
          Size( 8, 8 ), // gridStep
          optflow::INTERP_EPIC, // interp_type
          128, // epicK
          0.05f, // epicSigma
          1000.0f, // epicLambda
          15, // ricSPSize
          100, // ricSLICType
          true, // use_post_proc
          500.0f, // fgsLambda
          1.5f, // fgsSigma
          false // 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;
          }

运行结果

在这里插入图片描述

posted @ 2025-07-29 13:01  yjbjingcha  阅读(20)  评论(0)    收藏  举报