北京网站设计制作网站,公司注册号查询官网,网站自然排名工具,30号长沙封城最新消息操作系统#xff1a;ubuntu22.04 OpenCV版本#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言#xff1a;C11
算法描述
OpenCV CUDA 模块中实现的稀疏光流算法类#xff0c;基于 Lucas-Kanade 方法#xff0c;并支持图像金字塔结构。适用于特征点跟踪任务#xf… 操作系统ubuntu22.04 OpenCV版本OpenCV4.9 IDE:Visual Studio Code 编程语言C11
算法描述
OpenCV CUDA 模块中实现的稀疏光流算法类基于 Lucas-Kanade 方法并支持图像金字塔结构。适用于特征点跟踪任务如角点、FAST 特征等。
创建对象方法
静态函数create()
static Ptrcv::cuda::SparsePyrLKOpticalFlow cv::cuda::SparsePyrLKOpticalFlow::create(cv::Size winSize cv::Size(21, 21),int maxLevel 3,int iters 30,bool useInitialFlow false
);参数说明
参数名类型默认值描述winSizeSizeSize(21,21)Lucas-Kanade 算法使用的窗口大小必须为奇数maxLevelint3金字塔最大层级数0 表示不使用金字塔itersint30每层金字塔上的最大迭代次数useInitialFlowboolfalse是否使用初始 flow 输入
主要成员函数
深色版本
函数名返回类型描述calc()void计算两帧图像之间的稀疏光流getWinSize()Size获取当前窗口大小getMaxLevel()int获取金字塔最大层级getIterations()int获取每层迭代次数getUseInitialFlow()bool获取是否启用初始 flow 输入setUseInitialFlow(bool flag)void设置是否启用初始 flow 输入getStream()Stream获取当前使用的 CUDA 流setStream(const Stream stream)void设置使用的 CUDA 流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()
);参数说明
参数名类型描述prevImgInputArray前一帧图像灰度图CV_8UC1nextImgInputArray当前帧图像灰度图CV_8UC1prevPtsInputArray上一帧的特征点位置CV_32FC2 格式nextPtsInputOutputArray输出当前帧中对应点的位置CV_32FC2statusOutputArray输出每个点是否成功追踪uchar1 成功0 失败errOutputArray / noArray()可选输出误差值streamStream可选 CUDA 流默认为 Stream::Null()
注意事项与要求
条件要求输入图像格式必须为灰度图CV_8UC1关键点格式必须为 CV_32FC2 格式且是单行矩阵rows 1图像尺寸prevImg 和 nextImg 的尺寸必须相同实时性支持支持实时处理适合小数量关键点替代方案对于稠密光流请使用 DenseOpticalFlow 或 NvidiaOpticalFlow 系列接口
示例代码
#include opencv2/cudaimgproc.hpp
#include opencv2/cudaoptflow.hpp
#include opencv2/opencv.hppusing 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: 上传到 GPUGpuMat 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 格式 MatMat 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;
}运行结果