【问题标题】:OpenCV C++ MultithreadingOpenCV C++ 多线程
【发布时间】:2016-07-26 16:17:16
【问题描述】:

我在 4 个不同的 Mat 对象上调用了这个 opencv 图像处理函数 4x。

void processBinary(Mat& binaryMat) {
    //image processing
}

我想对它进行多线程处理,以便所有 4 个方法调用同时完成,但让主线程等待每个线程完成。

例如:

int main() {

    Mat m1, m2, m3, m4;

    //perform each of these methods simultaneously, but have main thread wait for all processBinary() calls to finish
    processBinary(m1);
    processBinary(m2);
    processBinary(m3);
    processsBinary(m4);
}

我希望实现的是能够根据需要多次调用 processBinary() 并且与只调用一次方法具有相同的效率。我已经查找了多线程,但是在调用线程然后加入/分离它们时有点困惑。我相信我需要实例化每个线程,然后在每个线程上调用 join() 以便主线程等待每个线程执行,但执行时间似乎没有显着增加。谁能解释我应该如何对我的程序进行多线程处理?谢谢!

编辑:我尝试过的:

//this does not significantly increase execution time. However, calling processBinary() only once does.4

    thread p1(&Detector::processBinary, *this, std::ref(m1));
    thread p2(&Detector::processBinary, *this, std::ref(m2));
    thread p3(&Detector::processBinary, *this, std::ref(m3));
    thread p4(&Detector::processBinary, *this, std::ref(m4));
    p1.join();
    p2.join();
    p3.join();
    p4.join();

【问题讨论】:

  • 你描述的工作是一个管道。每个函数都在获取前一阶段的输出。要实现并行性,您需要能够在工作流程的各个阶段之间移动较小的工作。换句话说,如果他们需要另一个任务的输出,他们怎么能并行工作。复制.. Findcontours...绘制轮廓....
  • 我不确定我是否理解。我想将 processBinary() 并行放置,因为它被称为 4x ,而不是方法内的代码。每个 processBinary() 在不同的 Mat 对象上调用,因此它们不相互依赖。
  • 啊...您应该添加调用processBinary 的代码。我们不需要 processBinary 的内部来帮助您并行化它的调用。
  • 对不起,我的解释很糟糕;我更新了这个问题,所以它更有意义:)
  • 你试过什么?如果processBinary 是一个纯函数,您只需生成 4 个标准线程并加入它们。

标签: c++ multithreading opencv


【解决方案1】:

实现这一点的巧妙方法不是自己进行线程内务管理,而是使用提供微并行化的库。

OpenCV 本身使用Intel Thread Building Blocks (TBB) 来完成这个任务——并行运行循环。

在您的情况下,您的循环只有四次迭代。使用 C++11,您可以使用 lambda 表达式非常轻松地写下来。在您的示例中:

std::vector<cv::Mat> input = { m1, m2, m3, m4; }
tbb::parallel_for(size_t(0), input.size(), size_t(1), [=](size_t i) {
    processBinary(input[i]); 
});

对于这个例子,我从here获取代码。

【讨论】:

  • 我会试试这个。我实际上是在尝试通过 ndk 在 android 上编译它,它似乎无法识别 包含。我检查了 sdk,libtbb.a 在那里......也许我的 Android.mk 设置不正确。你会碰巧知道这件事吗?可能需要另一个问题。
  • 不知道。
  • @SumeetBatra Intel tbb 是一个独立的库。如果您使用 tbb 支持构建它,则 Opencv 仅使用它。否则它使用你编译它的任何线程库。这可以是 pthreads、gdb 等。
  • @nnrales 这并不完全正确。 TBB 的用途与 pthread 不同。而gdb是一个什么样的线程库?
  • @nnrales TBB 和 GCD 是 pthread 之上的一层。 TBB 实际上在适用的情况下使用 pthreads 本身。如果您没有 TBB 或 GCD,则无法期望 OpenCV 提供相同的并行化。
【解决方案2】:

如果你使用的是 python 语言,那么你可以使用我强大的开源内置多线程 vidgear OpenCV 的包装 python 库在 GitHubPyPI 上可用实现更高的 FPS。

项目洞察:

VidGear 是围绕 OpenCV 视频 I/O 模块的轻量级 Python 包装器,其中包含强大的多线程模块(齿轮),可实现跨各种设备和平台的高速视频帧捕获功能。

特点:

它与其他现有多线程开源解决方案的主要区别在于:

  • 多线程高速 OpenCV 视频帧捕获(导致 高帧率)

  • 灵活的直接控制视频流,操作简单

  • 轻量级

  • 内置鲁棒错误和帧同步处理

  • 多平台兼容性(也兼容树莓派相机。

  • 完全支持网络视频流(包括 Gstreamer 原始视频) 捕获管道)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 2010-12-09
    • 1970-01-01
    相关资源
    最近更新 更多