OPenCV CUDA模块光流------高效地执行光流估计的类BroxOpticalFlow

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

算法描述

cv::cuda::BroxOpticalFlow 是 OpenCV CUDA 模块中实现Brox光流算法的类。该类用于在 GPU 上高效地计算两帧图像之间的稠密光流(Dense Optical Flow)。

什么是 Brox 光流?

Brox 光流算法是由 Thomas Brox 等人在 2004 年提出的一种基于变分法的稠密光流估计方法,它结合了:

  • 亮度一致性约束(Brightness Constancy Constraint)
  • 运动平滑性约束(Smoothness Constraint)
  • 梯度一致性约束(Gradient Constancy Constraint)

这个算法在准确性和鲁棒性方面表现良好,尤其适用于小到中等运动的场景。

cv::cuda::BroxOpticalFlow 类概述

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

创建与初始化

创建对象

cv::Ptr<cv::cuda::BroxOpticalFlow> brox = cv::cuda::BroxOpticalFlow::create
(float alpha,float gamma,float scale_factor,int inner_iterations,int outer_iterations,int solver_iterations
);
参数说明:
参数名类型含义
alphafloat控制光流平滑程度的正则化参数(越大越平滑)
gammafloat控制梯度一致性的权重
scale_factorfloat图像金字塔缩放因子(通常为 0.5 表示每层缩小一半)
inner_iterationsint内部迭代次数(求解线性系统)
outer_iterationsint外部迭代次数(优化整体光流场)
solver_iterationsint求解器每次迭代的次数(Jacobi 迭代次数)

使用流程

  1. 准备输入图像(必须是灰度图)
cv::Mat frame1_gray, frame2_gray;
cv::cvtColor(frame1, frame1_gray, cv::COLOR_BGR2GRAY);
cv::cvtColor(frame2, frame2_gray, cv::COLOR_BGR2GRAY);
  1. 转换为浮点格式并归一化([0, 1] 区间)
cv::Mat frame1_32f, frame2_32f;
frame1_gray.convertTo(frame1_32f, CV_32F, 1.0 / 255.0);
frame2_gray.convertTo(frame2_32f, CV_32F, 1.0 / 255.0);
  1. 上传图像到 GPU
cv::cuda::GpuMat d_frame1, d_frame2;
d_frame1.upload(frame1_32f);
d_frame2.upload(frame2_32f);
  1. 初始化 BroxOpticalFlow 对象
cv::Ptr<cv::cuda::BroxOpticalFlow> brox = cv::cuda::BroxOpticalFlow::create(0.197f,   // alpha50.0f,    // gamma0.8f,     // scale_factor10,       // inner_iterations77,       // outer_iterations10        // solver_iterations
);
  1. 创建输出矩阵(类型为 CV_32FC2)
cv::cuda::GpuMat d_flow;  // 输出光流,每个像素是一个 (dx, dy) 向量
  1. 执行光流计算
brox->calc(d_frame1, d_frame2, d_flow);
  1. 分离 flow_x 和 flow_y(可选)
std::vector<cv::cuda::GpuMat> flow_parts(2);
cv::split(d_flow, flow_parts);  // flow_parts[0] = dx, flow_parts[1] = dy
  1. 下载结果到 CPU(显示或保存用)
cv::Mat host_flowx, host_flowy;
flow_parts[0].download(host_flowx);
flow_parts[1].download(host_flowy);

代码示例

#include <opencv2/cudaimgproc.hpp>  // for split
#include <opencv2/cudaoptflow.hpp>  // for BroxOpticalFlow
#include <opencv2/opencv.hpp>       // core OpenCVusing namespace cv;
using namespace cv::cuda;int main()
{// Step 1: 加载图像std::string path1 = "/media/dingxin/data/study/OpenCV/sources/images/frame1.png";std::string path2 = "/media/dingxin/data/study/OpenCV/sources/images/frame2.png";Mat frame1 = imread(path1, IMREAD_GRAYSCALE);Mat frame2 = imread(path2, IMREAD_GRAYSCALE);if (frame1.empty() || frame2.empty()){std::cerr << "无法加载图像!路径:" << path1 << " 或 " << path2 << std::endl;return -1;}// Step 2: 转换为浮点格式 CV_32FC1 并归一化到 [0,1]Mat frame1_32f, frame2_32f;frame1.convertTo(frame1_32f, CV_32F, 1.0 / 255.0);frame2.convertTo(frame2_32f, CV_32F, 1.0 / 255.0);// Step 3: 上传到 GPUGpuMat d_frame1, d_frame2;d_frame1.upload(frame1_32f);d_frame2.upload(frame2_32f);// Step 4: 创建 BroxOpticalFlow 对象Ptr<BroxOpticalFlow> brox = BroxOpticalFlow::create();// Step 5: 创建输出矩阵(CV_32FC2 类型)GpuMat d_flow;// Step 6: 执行光流计算brox->calc(d_frame1, d_frame2, d_flow);// Step 7: 下载光流结果到CPUMat host_flow;d_flow.download(host_flow);  // 先下载到CPU// Step 8: 分离 flow_x 和 flow_y (在CPU上进行)std::vector<Mat> flow_parts(2);split(host_flow, flow_parts);  // 现在使用的是CPU上的cv::splitMat host_flowx = flow_parts[0];Mat host_flowy = flow_parts[1];// Step 9: 归一化显示Mat flowx_show, flowy_show;normalize(host_flowx, flowx_show, 0, 1, NORM_MINMAX, CV_32F);normalize(host_flowy, flowy_show, 0, 1, NORM_MINMAX, CV_32F);imshow("Flow X", flowx_show);imshow("Flow Y", flowy_show);// Step 10: 合成彩色光流图(HSV 表示方向和强度)Mat mag, ang;cartToPolar(host_flowx, host_flowy, mag, ang, true);  // 计算 magnitude & angleMat hsv_channels[3];hsv_channels[0] = ang;                              // Hue 表示方向hsv_channels[1] = Mat::ones(ang.size(), CV_32F);    // Saturation 固定最大hsv_channels[2] = mag;                              // Value 表示运动强度Mat hsv_merged, bgr_out;merge(hsv_channels, 3, hsv_merged);                    // 合并通道hsv_merged.convertTo(hsv_merged, CV_8U, 255);          // 转换为 0~255cv::cvtColor(hsv_merged, bgr_out, cv::COLOR_HSV2BGR);  // 显式使用 CPU 版本imshow("Optical Flow Color Map", bgr_out);waitKey(0);  // 等待按键关闭窗口return 0;
}

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视觉分析在人员行为属性检测中的应用

基于视觉分析的人员行为属性检测方案 一、背景与需求分析 在工业生产、建筑施工、公共安全等领域&#xff0c;人员行为属性的合规性检测是保障安全生产的关键环节。例如&#xff0c;工地工人未佩戴安全帽、厨房人员未佩戴手套、作业现场人员使用手机等行为&#xff0c;均可能…

Linux--进程的程序替换

问题导入&#xff1a; 前面我们知道了&#xff0c;fork之后&#xff0c;子进程会继承父进程的代码和“数据”&#xff08;写实拷贝&#xff09;。 那么如果我们需要子进程完全去完成一个自己的程序怎么办呢&#xff1f; 进程的程序替换来完成这个功能&#xff01; 1.替换原理…

场景题-3

如何实现一个消息队列 拆解分析主流的几种消息队列 1、基本架构 生产者Producer、消费者Consumer、Broker&#xff1a;生产者发送消息&#xff0c;消费者接受消息&#xff0c;Broker是服务端&#xff0c;处理消息的存储、备份、删除和消费关系的维护。 主题和分区&#xff…

vue2 项目中 npm run dev 运行98% after emitting CopyPlugin 卡死

今天在运行项目时&#xff0c;发现如下问题&#xff1a; 开始以为是node_modules依赖的问题&#xff0c;于是重新 npm install&#xff0c;重启项目后还是未解决。 在网上找了一圈发现有人说是 require引入图片地址没有写。在我的项目中排查没有这个问题&#xff0c;最后发现某…

73 LV的使用(XFS文件系统)

四 LV的使用 先创建一个LV01 lvcreate -L 10G lv01 datavg Logical volume "lv01" created. 将创建出来的LV01进行格式化 mkfs.xxx LV的名称(绝对路径) 绝对路径的组成:/dev/你创建VG的名字/LV的名字 mkfs.xfs /dev/datavg/lv01 挂载你的LV…

mybatis中判断等于字符串的条件怎么写

mybatis中判断等于字符串的条件怎么写_mybatis 等于字符串-CSDN博客 因为mybatis映射文件&#xff0c;是使用的ognl表达式&#xff0c;ognl是java语言&#xff08;强类型语言&#xff09;&#xff0c;会把‘X’解析成字符&#xff0c;而不是字符串。 所以比较字符串相等使用是…

C语言实现绝对值差值函数

在C语言中&#xff0c;可以编写一个函数来计算两个数的差值的绝对值。以下是一个简单的实现&#xff1a; #include <stdio.h> #include <stdlib.h> // 用于abs函数&#xff08;如果需要&#xff09; // 方法1&#xff1a;使用标准库函数 int absoluteDifference1…

Three.js中AR实现详解并详细介绍基于图像标记模式AR生成的详细步骤

文档地址 Three.js中AR实现详解 以下是Three.js中实现AR功能的详细解析&#xff0c;涵盖技术原理、实现步骤、核心组件及优化策略&#xff1a; &#x1f9e9; 一、技术基础 AR.js框架的核心作用 AR.js是Three.js实现AR的基石&#xff0c;提供以下核心能力&#xff1a; 多模…

Vue3.5 企业级管理系统实战(二十三):权限指令

在实际应用场景中&#xff0c;常常需要依据用户角色对按钮的操作权限实施控制。实现这一控制主要有两种方式&#xff1a;一种是借助前端指令基于角色进行权限管控&#xff0c;另一种是通过后台返回对应的权限属性来实现精细化控制。本文聚焦于前端权限指令展开探讨。 1 权限指…

软考 系统架构设计师系列知识点之杂项集萃(81)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;80&#xff09; 第145题 商业智能是企业对商业数据的搜集、管理和分析的系统过程&#xff0c;主要技术包括&#xff08;&#xff09;。 A. 数据仓库、联机分析和数据挖掘 B. 数据采集、数据清洗…

深入浅出Java ParallelStream:高效并行利器还是隐藏的陷阱?

在Java 8带来的众多革新中&#xff0c;Stream API彻底改变了我们对集合操作的方式。而其中最引人注目的特性之一便是parallelStream——它承诺只需简单调用一个方法&#xff0c;就能让数据处理任务自动并行化&#xff0c;充分利用多核CPU的优势。但在美好承诺的背后&#xff0c…

SQL Transactions(事务)、隔离机制

目录 Why Transactions? Example: Bad Interaction Transactions ACID Transactions COMMIT ROLLBACK How the Transaction Log Works How Data Is Stored Example: Interacting Processes Interleaving of Statements Example: Strange Interleaving Fixing the…

第R9周:阿尔茨海默病诊断(优化特征选择版)

文章目录 1. 导入数据2. 数据处理2.1 患病占比2.2 相关性分析2.3 年龄与患病探究 3. 特征选择4. 构建数据集4.1 数据集划分与标准化4.2 构建加载 5. 构建模型6. 模型训练6.1 构建训练函数6.2 构建测试函数6.3 设置超参数 7. 模型训练8. 模型评估8.1 结果图 8.2 混淆矩阵9. 总结…

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…

【大模型】大模型数据训练格式

1. SFT&#xff08;有监督微调&#xff09; 1.1 数据格式 JSONL&#xff08;每行一个 JSON 对象&#xff09;最为流行&#xff1b;也可用 CSV&#xff0f;TSV&#xff0c;但 JSONL 更灵活。字段设计 prompt&#xff1a;用户输入或任务指令&#xff08;通常以“系统指令&#…

[论文阅读] 人工智能 | 利用负信号蒸馏:用REDI框架提升LLM推理能力

【论文速读】利用负信号蒸馏&#xff1a;用REDI框架提升LLM推理能力 论文信息 arXiv:2505.24850 cs.LG cs.AI cs.CL Harnessing Negative Signals: Reinforcement Distillation from Teacher Data for LLM Reasoning Authors: Shuyao Xu, Cheng Peng, Jiangxuan Long, Weidi…

Cursor 1.0正式推出:全面解析你的AI 编程助手

目录 前言 一、BugBot&#xff1a;你的私人代码审查专家 二、Background Agent&#xff1a;7x24小时在线的云端开发伙伴 三、Jupyter Notebook 深度集成&#xff1a;数据科学家的福音 四、记忆功能 (Memories)&#xff1a;让 AI 更懂你的项目 五、MCP 与工具生态&#xf…

QILSTE 精巧电子元件H4-108FO/5M解析

型号&#xff1a;H4-108FO/5M 在电子元件的浩瀚宇宙中&#xff0c;H4-108FO/5M 仿佛一颗散发着独特光芒的恒星&#xff0c;其参数和特性交织成一张错综复杂的网络&#xff0c;既令人困惑又充满惊喜。这款型号的产品&#xff0c;以其 1.60.80.4mm 的微小尺寸&#xff0c;却蕴含…

第2章_Excel_知识点笔记

Excel 知识点总结&#xff08;第2章&#xff09; 来自&#xff1a;第2章_Excel_知识点笔记&#xff0c;原笔记 基础操作 状态栏&#xff1a;快速查看计数/求和等数据&#xff08;右键可配置&#xff09;。筛选&#xff08;CtrlShiftL&#xff09;&#xff1a;按条件显示数据…

【学习笔记】单例类模板

【学习笔记】单例类模板 一、单例类模板 以下为一个通用的单例模式框架&#xff0c;这种设计允许其他类通过继承Singleton模板类来轻松实现单例模式&#xff0c;而无需为每个类重复编写单例实现代码。 // 命名空间&#xff08;Namespace&#xff09; 和 模板&#xff08;Tem…