OpenCV CUDA 模块光流计算------稀疏光流算法类SparsePyrLKOpticalFlow_opencv 稀疏光流 gpu计算
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
OpenCV CUDA 模块中实现的稀疏光流算法类,基于 Lucas-Kanade 方法,并支持图像金字塔结构。适用于特征点跟踪任务(如角点、FAST 特征等)。
创建对象方法
静态函数:create()
static Ptr<cv::cuda::SparsePyrLKOpticalFlow> cv::cuda::SparsePyrLKOpticalFlow::create( cv::Size winSize = cv::Size(21, 21), int maxLevel = 3, int iters = 30, bool useInitialFlow = false);
参数说明:
Size
Size(21,21)
maxLevel
int
3
iters
int
30
useInitialFlow
bool
false
主要成员函数
深色版本
calc()
void
getWinSize()
Size
getMaxLevel()
int
getIterations()
int
getUseInitialFlow()
bool
setUseInitialFlow(bool flag)
void
getStream()
Stream&
setStream(const Stream& stream)
void
collectGarbage()
void
calc() 函数原型
void cv::cuda::SparsePyrLKOpticalFlow::calc( InputArray prevImg, // 前一帧图像 (灰度图 CV_8UC1) InputArray nextImg, // 当前帧图像 (灰度图 CV_8UC1) InputArray prevPts, // 上一帧中要追踪的点集 (CV_32FC2) InputOutputArray nextPts, // 输出:当前帧中追踪到的点集 OutputArray status, // 输出:每个点是否成功追踪 (uchar) OutputArray err = noArray(), // 可选输出:误差值 Stream& stream = Stream::Null());
参数说明:
prevImg
InputArray
nextImg
InputArray
prevPts
InputArray
nextPts
InputOutputArray
status
OutputArray
err
OutputArray
/ noArray()
stream
Stream&
Stream::Null()
注意事项与要求
CV_32FC2
格式,且是单行矩阵(rows == 1
)prevImg
和 nextImg
的尺寸必须相同DenseOpticalFlow
或 NvidiaOpticalFlow
系列接口示例代码
#include #include #include using namespace cv;using namespace cv::cuda;int main(){ // Step 1: 读取两帧图像(灰度图) Mat frame1 = imread( \"/media/dingxin/data/study/OpenCV/sources/images/frame1.png\", IMREAD_GRAYSCALE ); Mat frame2 = imread( \"/media/dingxin/data/study/OpenCV/sources/images/frame2.png\", IMREAD_GRAYSCALE ); if ( frame1.empty() || frame2.empty() ) { std::cerr << \"无法加载图像\" << std::endl; return -1; } // Step 2: 上传到 GPU GpuMat d_frame1, d_frame2; d_frame1.upload( frame1 ); d_frame2.upload( frame2 ); // Step 3: 检测角点作为追踪起点 std::vector< Point2f > corners; goodFeaturesToTrack( frame1, corners, 500, 0.01, 10 ); // 最多检测500个角点 // Step 4: 转换为 GPU 可用数组 GpuMat d_prevPts; // 构造一行多列的 CV_32FC2 格式 Mat Mat m_prevPts( 1, corners.size(), CV_32FC2 ); for ( size_t i = 0; i < corners.size(); ++i ) { m_prevPts.at< cv::Vec2f >( 0, i ) = cv::Vec2f( corners[ i ].x, corners[ i ].y ); } d_prevPts.upload( m_prevPts ); // Step 5: 创建稀疏光流对象 Ptr< cuda::SparsePyrLKOpticalFlow > lk = cuda::SparsePyrLKOpticalFlow::create(); // Step 6: 准备输出变量 GpuMat d_nextPts; GpuMat d_status; GpuMat d_err; // Step 7: 计算稀疏光流 lk->calc( d_frame1, d_frame2, d_prevPts, d_nextPts, d_status, d_err ); // Step 8: 下载结果 Mat nextPts, status; d_nextPts.download( nextPts ); d_status.download( status ); // Step 9: 绘制跟踪结果 Mat output; cv::cvtColor( frame1, output, COLOR_GRAY2BGR ); // 注意:status 和 nextPts 都是单行矩阵,所以使用 (0, i) for ( int i = 0; i < status.cols; ++i ) { if ( ( int )status.at< uchar >( 0, i ) == 1 ) { Point2f pt1 = corners[ i ]; Point2f pt2 = nextPts.at< Point2f >( 0, i ); // 确保点在图像范围内 if ( pt2.x >= 0 && pt2.y >= 0 && pt2.x < frame1.cols && pt2.y < frame1.rows ) { line( output, pt1, pt2, Scalar( 0, 255, 0 ), 1 ); circle( output, pt2, 2, Scalar( 0, 0, 255 ), -1 ); } } } imshow( \"Sparse PyrLK Optical Flow\", output ); waitKey( 0 ); return 0;}