OpenCV CUDA模块光流计算-----实现Farneback光流算法的类cv::cuda::FarnebackOpticalFlow

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

算法描述

cv::cuda::FarnebackOpticalFlow 是 OpenCV CUDA 模块中实现 Farneback 光流算法 的类。该类用于在 GPU 上高效地计算两帧图像之间的稠密光流(Dense Optical Flow),特别适合视频分析和运动估计。

类定义概览

属性 说明
头文件 <opencv2/cudaoptflow.hpp>
命名空间 cv::cuda
继承自 cv::cuda::DenseOpticalFlow
用途 计算两个图像帧之间的稠密光流(每个像素都有一个运动向量)
GPU 加速 支持 CUDA GPU 加速

创建与初始化

创建对象

cpp 复制代码
cv::Ptr<cv::cuda::FarnebackOpticalFlow> farneback = cv::cuda::FarnebackOpticalFlow::create();

你也可以通过设置参数来定制化这个对象:

cpp 复制代码
cv::Ptr<cv::cuda::FarnebackOpticalFlow> farneback = cv::cuda::FarnebackOpticalFlow::create(
    int numLevels = 5,           // 图像金字塔的层数
    double pyrScale = 0.5,       // 金字塔缩放因子
    bool fastPyramids = false,   // 是否使用快速金字塔构建
    int winSize = 13,            // 滑动窗口大小
    int numIters = 10,           // 迭代次数
    int polyN = 5,               // 多项式展开邻域大小
    double polySigma = 1.1,      // 高斯权重的标准差
    int flags = 0                // 标志位
);

或者,你可以创建默认对象后单独设置参数:

cpp 复制代码
farneback->setNumLevels(5);          // 设置金字塔层数
farneback->setPyrScale(0.5);         // 设置金字塔缩放因子
farneback->setFastPyramids(false);   // 是否使用快速金字塔
farneback->setWinSize(13);           // 设置滑动窗口大小
farneback->setNumIters(10);          // 设置迭代次数
farneback->setPolyN(5);              // 设置多项式展开邻域大小
farneback->setPolySigma(1.1);        // 设置高斯权重的标准差
farneback->setFlags(0);              // 设置标志位

代码示例

cpp 复制代码
#include <opencv2/cudaimgproc.hpp>  // for upload/download
#include <opencv2/cudaoptflow.hpp>
#include <opencv2/opencv.hpp>  // for imread, imshow 等

int main()
{
    // Step 1: 加载灰度图像
    cv::Mat frame1 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/frame1.png", cv::IMREAD_GRAYSCALE );
    cv::Mat frame2 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/frame2.png", cv::IMREAD_GRAYSCALE );
if (frame1.empty() || frame2.empty()) {
        std::cerr << "无法加载图像" << std::endl;
        return -1;
    }

    // Step 2: 上传到 GPU
    cv::cuda::GpuMat d_frame1, d_frame2;
    d_frame1.upload(frame1);
    d_frame2.upload(frame2);

    // Step 3: 创建 FarnebackOpticalFlow 对象,并设置参数
    cv::Ptr<cv::cuda::FarnebackOpticalFlow> farneback =
        cv::cuda::FarnebackOpticalFlow::create(
            5,       // numLevels
            0.5,     // pyrScale
            false,   // fastPyramids
            21,      // winSize
            20,      // numIters
            7,       // polyN
            1.5,     // polySigma
            0        // flags
        );

    // Step 4: 准备输出 flow 图像(CV_32FC2)
    cv::cuda::GpuMat d_flow;
    farneback->calc(d_frame1, d_frame2, d_flow);

    // Step 5: 下载结果到 CPU
    cv::Mat host_flow;
    d_flow.download(host_flow);  // CV_32FC2

    // Step 6: 分离 dx 和 dy 通道
    std::vector<cv::Mat> flow_parts(2);
    cv::split(host_flow, flow_parts);  // flow_parts[0] = dx, flow_parts[1] = dy

    // Step 7: 计算 magnitude 和 angle
    cv::Mat mag, ang;
    cv::cartToPolar(flow_parts[0], flow_parts[1], mag, ang, true);  // 角度单位为 degree

    // Step 8: 构建 HSV 图像
    std::vector<cv::Mat> hsv_channels;

    // Hue: 角度归一化到 [0, 1]
    ang.convertTo(ang, CV_32F);
    ang = ang.mul(cv::Mat::ones(ang.size(), CV_32F) / 360.0f);  // [0, 1]

    // Saturation: 固定最大
    cv::Mat sat = cv::Mat::ones(ang.size(), CV_32F) * 255;  // [0, 255]

    // Value: magnitude 归一化到 [0, 255]
    cv::Mat val;
    cv::normalize(mag, val, 0, 255, cv::NORM_MINMAX, CV_32F);

    // 合并通道
    hsv_channels.push_back(ang);   // H: [0, 1]
    hsv_channels.push_back(sat);   // S: [0, 255]
    hsv_channels.push_back(val);   // V: [0, 255]

    cv::Mat hsv_merged;
    cv::merge(hsv_channels, hsv_merged);

    // Step 9: 转换为 BGR 显示
    cv::Mat bgr_out;
    hsv_merged.convertTo(hsv_merged, CV_8U);  // 必须先转成 8U
    cv::cvtColor(hsv_merged, bgr_out, cv::COLOR_HSV2BGR);

    // Step 10: 显示图像
    cv::imshow("Optical Flow (Magnitude)", mag);
    cv::imshow("Optical Flow (Angle)", ang);
    cv::imshow("Optical Flow (HSV)", bgr_out);
    cv::waitKey(0);

    return 0;
}

运行结果

相关推荐
whoarethenext2 分钟前
使用 C++/OpenCV 创建动态流星雨特效 (实时动画)
开发语言·c++·opencv
whoarethenext5 分钟前
使用 C/C++的OpenCV 实现模板匹配:从基础到优化
c语言·c++·opencv
ywyy679819 分钟前
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
人工智能·小程序·短剧·推客系统·推客小程序·推客系统开发·推客小程序开发
加百力27 分钟前
自动驾驶+人形机器人?亚马逊即将测试人形机器人送货
人工智能·机器人·自动驾驶
强盛小灵通专卖员29 分钟前
基于深度学习RT-DETR算法的盲人障碍物目标检测:提升盲人出行安全的智能化突破
深度学习·算法·目标检测·计算机视觉·rt-detr·小论文·计算机期刊
落沐萧萧1 小时前
本地多语言 AI 字幕组:Whisper 实战教程
人工智能·whisper
合方圆~小文1 小时前
架空线路图像视频监测装置
c语言·c++·人工智能·嵌入式硬件·硬件工程·模拟退火算法
小草cys1 小时前
使用 Coze 工作流一键生成抖音书单视频:全流程拆解与技术实现
人工智能·音视频·工作流·coze
我不是小upper1 小时前
统计学核心概念与现实应用精解(偏机器学习)
算法·机器学习·统计学
Renlijuande1 小时前
百度之星2021——BD202104 萌新
算法