- 操作系统: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;
}
运行结果
