OpenCV用于计算光流的一个类cv::optflow::DualTVL1OpticalFlow

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

cv::optflow::DualTVL1OpticalFlow 是 OpenCV 中用于计算光流的一个类,特别地,它实现了基于双帧 TV-L1(Total Variation - L1)模型的光流算法。这种算法以其在处理速度和准确性之间的良好平衡而著称,并且对光照变化具有一定的鲁棒性。

以下是关于 cv::optflow::DualTVL1OpticalFlow 类的一些基本信息:

主要特点

  • 高效性与准确性:该算法在保持较高精度的同时提供了相对快速的计算速度。
  • 鲁棒性:对于光照变化、噪声等具有一定抵抗能力。
  • 参数调节:支持多种参数调整,以便针对不同的应用场景进行优化。

成员函数介绍

✅ 静态创建函数

cpp 复制代码
static Ptr<DualTVL1OpticalFlow> create();
复制代码
创建一个默认参数配置的 DualTVL1OpticalFlow 实例。

✅ 核心计算函数

cpp 复制代码
void calc(
    InputArray I0,           // 第一帧图像(灰度图)
    InputArray I1,           // 第二帧图像(灰度图)
    InputOutputArray flow    // 输出光流(2通道图像,每个像素为 (u, v))
);
复制代码
用于计算两帧图像之间的光流。

✅ 参数设置函数

函数名 描述
setTau(double val) 设置时间步长(迭代优化的步长)
setLambda(double val) 设置平滑项权重(越大越平滑)
setTheta(double val) 设置对偶变量的松弛因子
setGamma(double val) 设置数据项的正则化参数
setScalesNumber(int val) 设置图像金字塔层数
setWarpingsNumber(int val) 设置 warp 迭代次数
setEpsilon(double val) 设置收敛精度
setMaxIters(int val) 设置最大迭代次数

代码示例

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/optflow.hpp>

using namespace cv;
using namespace std;

// 可视化光流向量为 HSV 图像
Mat visualizeFlow( const Mat& flow )
{
    vector< Mat > planes;
    split( flow, planes );

    Mat mag, angle;
    cartToPolar( planes[ 0 ], planes[ 1 ], mag, angle, true );
    normalize( mag, mag, 0, 1, NORM_MINMAX );

    Mat hsv[ 3 ];
    hsv[ 0 ] = angle;
    hsv[ 1 ] = Mat::ones( angle.size(), CV_32F );
    hsv[ 2 ] = mag;

    Mat hsvFull;
    merge( hsv, 3, hsvFull );
    hsvFull.convertTo( hsvFull, CV_8U, 255.0 );
    Mat rgbOut;
    cvtColor( hsvFull, rgbOut, COLOR_HSV2BGR );

    return rgbOut;
}

int main()
{
    // 加载两帧灰度图像
    Mat frame1 = imread( "/media/dingxin/data/study/OpenCV/sources/images/left01.jpg", IMREAD_GRAYSCALE );
    Mat frame2 = imread( "/media/dingxin/data/study/OpenCV/sources/images/right01.jpg", IMREAD_GRAYSCALE );

    if ( frame1.empty() || frame2.empty() )
    {
        cerr << "无法加载图像!" << endl;
        return -1;
    }

    // 创建 DualTVL1 实例
    Ptr< optflow::DualTVL1OpticalFlow > tvl1 = optflow::DualTVL1OpticalFlow::create();

    // 计算稠密光流
    Mat flow;
    tvl1->calc( frame1, frame2, flow );

    // 可视化并显示
    Mat flowImage = visualizeFlow( flow );
    imshow( "Frame 1", frame1 );
    imshow( "Frame 2", frame2 );
    imshow( "Dual TV-L1 Optical Flow", flowImage );
    waitKey( 0 );

    return 0;
}

运行结果