OpenCV GPU Farneback 光流在多线程中表现不佳

2024-04-19

我的应用程序使用 Opencv GPU 类gpu::FarnebackOpticalFlow计算输入视频的一对连续帧之间的光流。为了加速该过程,我利用 OpenCV 的 TBB 支持在多线程中运行该方法。然而,多线程性能并不像单线程那样。为了让您了解不同的行为,这里有两个快照,分别是单线程和多线程实现的。

多线程实现假设将图像分割为 8 个不同的条带(我的电脑上的核心数量),并且将用于光流的 Farneback 实现的 GPU 方法应用于每个条带。以下是这两种方法对应的代码行:

单线程实现

/* main.cpp */
//prevImg and img are the input Mat images extracted from the input video
...
GpuMat gpuImg8U(img);
GpuMat gpuPrevImg8U(prevImg);   
GpuMat u_flow, v_flow;
gpu::FarnebackOpticalFlow farneback_flow;
farneback_flow.numLevels = maxLayer;
farneback_flow.pyrScale = 0.5;
farneback_flow.winSize = windows_size;
farneback_flow.numIters = of_iterations;
farneback_flow(gpuPrevImg8U,gpuImg8U,u_flow,v_flow);
getFlowField(Mat(u_flow),Mat(v_flow),optical_flow);

...
}

void getFlowField(const Mat& u, const Mat& v, Mat& flowField){    
    for (int i = 0; i < flowField.rows; ++i){
        const float* ptr_u = u.ptr<float>(i);
        const float* ptr_v = v.ptr<float>(i);
        Point2f* row = flowField.ptr<Point2f>(i);

        for (int j = 0; j < flowField.cols; ++j){
            row[j].y = ptr_v[j];
            row[j].x = ptr_u[j];
        }
    }
}

多线程实现

/* parallel.h */
class ParallelOpticalFlow : public cv::ParallelLoopBody {

    private:
        int coreNum;
        cv::gpu::GpuMat img, img2;
        cv::gpu::FarnebackOpticalFlow& farneback_flow;
        const cv::gpu::GpuMat u_flow, v_flow;
        cv::Mat& optical_flow;

    public:
        ParallelOpticalFlow(int cores, cv::gpu::FarnebackOpticalFlow& flowHandler, cv::gpu::GpuMat img_, cv::gpu::GpuMat img2_, const cv::gpu::GpuMat u, const cv::gpu::GpuMat v, cv::Mat& of)
                    : coreNum(cores), farneback_flow(flowHandler), img(img_), img2(img2_), u_flow(u), v_flow(v), optical_flow(of){}

        virtual void operator()(const cv::Range& range) const;

};


/* parallel.cpp*/
void ParallelOpticalFlow::operator()(const cv::Range& range) const {

    for (int k = range.start ; k < range.end ; k ++){

        cv::gpu::GpuMat img_rect(img,cv::Rect(0,img.rows/coreNum*k,img.cols,img.rows/coreNum));
        cv::gpu::GpuMat img2_rect(img2,cv::Rect(0,img2.rows/coreNum*k,img2.cols,img2.rows/coreNum));
        cv::gpu::GpuMat u_rect(u_flow,cv::Rect(0,u_flow.rows/coreNum*k,u_flow.cols,u_flow.rows/coreNum));
        cv::gpu::GpuMat v_rect(v_flow,cv::Rect(0,v_flow.rows/coreNum*k,v_flow.cols,v_flow.rows/coreNum));
        cv::Mat of_rect(optical_flow,cv::Rect(0,optical_flow.rows/coreNum*k,optical_flow.cols,optical_flow.rows/coreNum));

        farneback_flow(img_rect,img2_rect,u_rect,v_rect);
        getFlowField(Mat(u_rect),Mat(v_rect),of_rect);
    }
}

/* main.cpp */

    parallel_for_(Range(0,cores_num),ParallelOpticalFlow(cores_num,farneback_flow,gpuPrevImg8U,gpuImg8U,u_flow,v_flow,optical_flow));

这两种情况下的代码看起来是等效的。谁能解释一下为什么会有这些不同的行为?或者如果我的代码中有一些错误? 预先感谢您的回答


GPU 模块不是线程安全的。它使用一些全局变量,例如__constant__内存和纹理参考 API,如果在多线程环境中使用,可能会导致数据竞争。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV GPU Farneback 光流在多线程中表现不佳 的相关文章

  • MySql 最后插入 ID,连接器 .net

    我正在使用 MySql Connector net 我需要获取最后一个查询生成的插入 id 现在 我假设返回值是MySqlHelper ExecuteNonQuery应该是最后一个插入id 但它只返回1 我正在使用的代码是 int inse
  • 在调用堆栈中看到大量 clr!CLR Semaphore::Wait

    我们看到很多像下面这样的调用堆栈 我可以知道什么条件 情况会发生这种情况吗 OS Thread Id 0x48654 559 Current frame ntdll NtWaitForSingleObject 0xa Child SP Re
  • 使用预编译头减少 clang 编译时间

    我正在开发一个数据库项目 该项目将查询 以某种高级语言表示 编译为 C 代码 这段代码由数据库编译并执行 那部分工作得很好 现在 我正在尝试减少 C 查询代码的编译时间 我想知道是否可以使用预编译头来提高性能 该查询被转换为一个名为 Que
  • 宏可以按参数数量重载吗?

    如何this https stackoverflow com q 9183993 153285工作 如何实现 C99 C 11 可变参数宏以仅根据为其提供多少个参数来扩展到不同的事物 编辑 请参阅末尾以获得现成的解决方案 要获得重载的宏 首
  • StreamReader,C#,peek

    我有一个 StreamReader 它偶尔会检查它是否有更多内容可以从简单的文本文件中读取 它使用 peek 属性 问题是 当我使用 peek 时 位置发生了变化 尽管不应该发生 FileStream m fsReader new File
  • 有没有办法将 boost::json::serializer 切换为美化输出?

    Using boost json serializer如中的示例所示文档 快速查看 http vinniefalco github io doc json json usage quick look html以紧凑格式保存 json tre
  • 是否有一种算法可以在线性时间内计算数组反转?

    我知道有多少倒转 en wikipedia org wiki Inversion 28discrete mathematics 29 in an n 元素数组可以在 O n log n 操作使用增强型归并排序 http www geeksf
  • 命名空间“Microsoft”中不存在类型或命名空间名称“Practices”

    我正在使用 Microsoft Visual Studio 2005 for c 我的代码中有以下命名空间 using Microsoft Practices EnterpriseLibrary using Microsoft Practi
  • ASP.NET MVC 路由 - 向路由添加 .html 扩展名

    我对 MVC 和路由非常陌生 我被要求修改一个应用程序以使用不同的 url 由于我没有经验 这项任务对我来说有点困难 好吧 让我们谈谈一些代码 routes MapRoute CategoryBySeName Route name prod
  • 使用 INotifyPropertyChanged

    有人可以解释一下为什么在 wpf 中使用绑定时需要使用 INotifyPropertyChanged 的 实现吗 我可以在不实现此接口的情况下绑定属性吗 例如我有代码 public class StudentData INotifyProp
  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • 参数数量在编译时确定的 Lambda 函数

    我想声明一个带有 N 个参数的 lambda 函数 其中 N 是模板参数 就像是 template
  • 为什么我不能对普通变量进行多态?

    我是一名Java程序员 最近开始学习C 我对某事感到困惑 据我了解 在 C 中 要实现多态行为 您必须使用指针或引用 例如 考虑一个类Shape与实施的方法getArea 它有几个子类 每个子类都以不同的方式重写 getArea 然后考虑以
  • 未找到 _sqlite3_open 等符号错误

    您好 我收到此错误 Undefined symbols sqlite3 open referenced from main in ccRlWVer o sqliite3 close referenced from main in ccRlW
  • 为什么调试器只显示数组指针中的一个元素?

    首先 我知道new是执行此操作的 C 方法 我只是表明有不止一种方法可以重现此错误 而且两种方法都令人难以置信的令人沮丧 我有两种形式的源文件 我正在尝试调试另一个编程作业 但我并没有寻求帮助 基本上 我正在尝试重新实施set作为一个类 具
  • 获取会议组织者邮件地址 EWS API

    我想使用 EWS API 获取会议组织者的邮件地址 目前 我刚刚获得约会项目的一些属性 我听说你可以设置你想要获取哪些属性 我的代码看起来像这样 CalendarView cview new CalendarView start end c
  • 清理堆分配对象的良好实践或约定?

    我正在学习C 我有 C C ObjC 背景 相当高级的语言 在 C 或 ObjC 上 作为函数或方法的结果返回堆分配的对象是很简单的 因为对象的清理是受管理的 按照惯例 会在适当的时候销毁 但我不知道在 C 中应该如何处理这个问题 例如 s
  • 如何从尖点库矩阵格式获取原始指针

    我需要从尖点库矩阵格式获取原始指针 例如 cusp coo matrix
  • 如何在没有 Visual Studio 的情况下将新文件添加到 .csproj 文件

    如何添加新文件到 csproj从命令提示符 我认为没有任何工具可以响应命令行上的 add project 命令来执行此操作 但我认为您可以幸运地创建一个程序 脚本来直接操作 csproj 文件的 XML 内容 csproj 文件的结构如下所
  • C# amo 获取角色完整

    我正在开发一个 SSAS 项目 其中除其他事项外 我需要获取 C 中表格多维数据集的完整用户列表 目前我让它以这样的方式工作 我可以获得角色 但数据不完整 当我调用 Server Database Roles 为了便于阅读而简化 属性并枚举

随机推荐

  • 使用 fb_graph Ruby gem 从 Facebook 检索好友位置

    我正在尝试使用 gem 检索用户所有朋友的位置 fb graph https github com nov fb graph 版本1 7 2 我的权限是 发布流 读取好友列表 离线访问 好友位置 用户位置 我已经对用户进行了身份验证并存储了
  • “不支持”在不指定 RuntimeIdentifier 的情况下构建或发布独立的应用程序

    使用最新的 Visual Studio 2019 我尝试发布 DotNetCore 3 1 WPF 应用程序的 Msix 安装程序 应用程序构建并正确运行 但是当我尝试发布应用程序时出现此错误 It is not supported to
  • 迭代 DFS 与递归 DFS 以及不同的元素顺序

    我编写了一个递归 DFS 算法来遍历图 void Graph
  • eclipse 烦恼:调试和启动工具栏不可用

    我正在运行 Windows XP 和 Eclipse 4 2 2 Build id M20130204 1200 并且我丢失了调试和启动工具栏 我尝试过 Windows gt 重置透视 原始值 和窗口 gt 自定义透视 工具栏可见性和命令组
  • JavaScript 中的错误:对象不是函数

    当我运行下面的代码时 它显示错误object is not a function在控制台中 这个错误就在这一行var todo new Todo contents in my script js文件 我怎样才能让它发挥作用 这是我的 tod
  • 监控网络连接带宽的最佳工具

    我正在寻找一个非常简单的工具来监控所有应用程序的带宽 不需要流量监视等额外功能 我只是对带宽感兴趣 我已经知道 Wireshark 这很棒 但我正在寻找更多类似 TcpView 来自 Sysinternals 的出色工具 以及当前带宽指示的
  • Rails、activerecord 求和然后排序

    我有一个属于用户的工作模型 并且用户有很多工作 我想创建一个 AR 查询来计算每个用户的总工作日数 然后按降序排列 到目前为止 我已经有了这个 但给了我一个错误 列 Job id 必须出现在 GROUP BY 子句中或在聚合函数中使用 wo
  • Phonegap - 在插件委托中从 Objective-c 向 Javascript 发送消息

    我有一个 Phonegap Cordova 插件 在此插件中 我收到来自 javascript 的点击事件 此点击触发使用我的客户端库的文件下载 此文件下载发送事件并调用我的插件中的方法 因为我已将其设置为委托 我无法使用 stringBy
  • java.lang.NoSuchFieldError:没有 Landroidx/compose/foundation/layout/BoxScope$Companion 类型的字段 Companion;

    我是第一次使用 Jetpack Compose 但收到此错误 我还没有弄清楚问题到底出在哪里 但我正在使用单活动架构 如果需要更多信息 请通知我 根据错误信息 问题似乎出在脚手架上 val scaffoldState rememberSca
  • 添加应用程序时 Firebase 数据库被删除

    好的 所以我正在构建一个将在 Play 商店上运行的应用程序 它具有将数据添加到 Firebase 的功能 它无法读取数据 第二个应用程序将保留在我身边 它不会出现在游戏商店中 它用于读取数据 现在我所做的是 假设第一个应用程序有包名称 c
  • 有目的地回到之前的活动

    我有两个活动 当我在第一个活动上按 Enter 时 它将打开第二个活动 它包含一个ListView当我从中选择一个项目时ListView 它将获得其值并返回到第一个活动 这就是我尝试过的 在第二项活动中 listPerasat setOnI
  • R:随机采样抛硬币组

    我正在使用 R 编程语言 Suppose 有一枚硬币 如果它正面朝上 那么下一次抛掷正面的概率是 0 6 如果是反面 那么下一次抛掷反面的概率也是 0 6 一个班有100名学生 每个学生随机抛掷硬币几次 Student n 的最后一次抛硬币
  • Iframe/CSS:强制 Iframe 适合屏幕

    我目前正在尝试让 iframe 适合我的屏幕尺寸 以及任何其他以不同分辨率使用它的用户 除非无论我尝试什么 最终都会导致 iframe 太小或高度太大导致双滚动条 iframe 和页面本身有滚动条 我的目标是让 iframe 仅适合页面宽度
  • CUDA程序导致nvidia驱动程序崩溃

    当我超过大约 500 次试验和 256 个完整块时 我的 monte carlo pi 计算 CUDA 程序导致我的 nvidia 驱动程序崩溃 这似乎发生在 monteCarlo 内核函数中 任何帮助都会受到赞赏 include
  • IMAP fetch() 返回命令错误:BAD [b' 命令参数错误。 12']

    我无法在网上找到示例 故障排除提示 并且不太确定我是否正确解释了文档 任何帮助将不胜感激 我正在连接到电子邮件服务器 并且想要阅读电子邮件主题和正文 我首先像这样建立连接 import imaplib c imaplib IMAP4 SSL
  • 如何在 Ruby 中使用模块重写静态类方法?

    module Imodule end class Some include Imodule def self imethod puts original end end Some imethod gt overrided 如何创建一个将覆盖
  • acts_as_taggable_on:如何优化查询?

    I use acts as taggable on在我当前的 Rails 项目中 在一个概述页面上 我显示了对象及其关联标签的索引 我使用以下代码 class Project lt ActiveRecord Base acts as tag
  • “Windows”键作为快捷键的一部分

    I very often open a console window while doing my development Usually Win R gt cmd gt enter However Windows also lets yo
  • 从 Android 中的“我的应用程序”发送彩信

    我想将彩信从我的应用程序发送到特定号码 我已经搜索并找到了这段代码 但我不知道这段代码是否是我需要的 我的问题是 任何人都可以向我解释这段代码 我是彩信初学者 另外 我认为这段代码是让用户从我的应用程序发送彩信 而不将其移动到本机消息收件箱
  • OpenCV GPU Farneback 光流在多线程中表现不佳

    我的应用程序使用 Opencv GPU 类gpu FarnebackOpticalFlow计算输入视频的一对连续帧之间的光流 为了加速该过程 我利用 OpenCV 的 TBB 支持在多线程中运行该方法 然而 多线程性能并不像单线程那样 为了