提高图像处理速度

Posted

技术标签:

【中文标题】提高图像处理速度【英文标题】:Improving image processing speed 【发布时间】:2012-01-27 20:12:21 【问题描述】:

我正在使用 C++ 和 OpenCV 实时处理从网络摄像头拍摄的一些图像,我希望从我的系统中获得最佳速度。

除了更改处理算法(暂时假设您无法更改它)。我应该做些什么来最大限度地提高处理速度?

我在想也许多线程在这里可以有所帮助,但我很惭愧地说我并不真正了解其中的来龙去脉(尽管显然我以前使用过多线程,但在 C++ 中没有使用过)。

假设我有一个 x 核处理器,将处理拆分为 x 个线程实际上会加快速度吗?...或者假设我正在寻找 20fps 的吞吐量,这些线程的管理开销是否会否定它(我假设这会影响你给出的答案,因为它应该告诉你每个线程将完成多少处理)

多线程在这里有用吗?

有没有什么技巧可以专门提高 OpenCV 的速度,或者我可能会陷入降低速度的任何陷阱。

谢谢。

【问题讨论】:

将每个传入的帧扔给一组旋转的线程应该允许死简单的多线程。 【参考方案1】:

我认为,更简单的方法可能是流水线化框架操作。

您可以使用线程池,将帧内存缓冲区顺序分配给第一个可用线程,以便在相关帧上的算法步骤完成时释放到池中。

这实际上可以使您当前的(已调试的:)算法保持不变,但需要更多的内存来缓冲中间结果。

当然,如果没有关于你的任务的详细信息,很难说这是否合适......

【讨论】:

【参考方案2】:

在 OpenCV 中提高速度有一件重要的事情,与处理器或算法无关,它在处理矩阵时避免额外的复制。我会给你一个取自文档的例子:

"...通过为另一个矩阵的一部分构造标题。它可以是 单行、单列、多行、多列、矩形 矩阵中的区域(在代数中称为次要)或对角线。这样的 操作也是 O(1),因为新标头将引用 相同的数据。您实际上可以使用此修改矩阵的一部分 特征,例如”

// add 5-th row, multiplied by 3 to the 3rd row
M.row(3) = M.row(3) + M.row(5)*3;

// now copy 7-th column to the 1-st column
// M.col(1) = M.col(7); // this will not work
Mat M1 = M.col(1);
M.col(7).copyTo(M1);

也许您已经知道这个问题,但我认为在 openCV 中突出显示 headers 作为一种重要且高效的编码工具非常重要。

【讨论】:

【参考方案3】:

假设我有一个 x 核处理器,将处理拆分为 x 个线程实际上会加快处理速度吗?

是的,尽管这在很大程度上取决于所使用的特定算法,以及您编写线程代码以处理诸如同步之类的事情的技能。您确实没有提供足够的细节来做出比这更好的评估。

一些算法非常容易并行化,例如具有以下形式的算法:

for (i=0; i < DATA_SIZE; i++)

   output[i] = f(input[i]);

对于某些函数 f。这些被称为embarassingly parallelizable;您可以简单地将数据拆分为 N 个块,并让 N 个线程单独处理每个块。像 OpenMP 这样的库使这种线程非常简单。

【讨论】:

【参考方案4】:

除非您使用的特定算法已经针对多线程/并行平台进行了优化,否则将其扔给 x 核处理器对您毫无用处。该算法必须本质上是可线程的,才能从多个线程中受益。但如果它的设计没有考虑到这一点,它就必须改变。另一方面,许多图像处理算法是“令人尴尬的并行”,至少在概念上是这样。你能分享更多关于你想到的算法的细节吗?

【讨论】:

好吧,目前我只是使用标准的 OpenCV 算法来“填补处理的空白”。 (顺便说一句,它们是多线程/优化的吗?).....我实际上还没有决定我要使用的算法,但它可能是一个逐像素的分析,如果需要我可以分成 x 个线程并让他们都返回一个结果。 算法在代码中实现。代码本质上是线程安全的,因此它取决于数据。 @MartinJames,代码大部分是线程安全的——你必须避免在你的代码中使用可变的静态变量。 所有代码都是线程安全的,除非是自修改的。可变静态是数据。 @MartinJames 真的不明白你的意思。【参考方案5】:

如果您的线程可以对不同的数据进行操作,那么将其线程化似乎是合理的,也许将每个帧对象排队到线程池中。您可能必须向帧对象添加序列号,以确保从池中出现的已处理帧按照它们进入的顺序传递。

【讨论】:

【参考方案6】:

作为使用 OpenCV 进行多线程图像处理的示例代码,您可能需要查看我的代码:

https://github.com/vmlaker/sherlock-cpp

这就是我想利用 x-core CPU 来提高对象检测性能的想法。 detect 程序基本上是一种在多个线程之间分配任务的并行算法,每个任务都有一个单独的流水线线程:

    分配帧内存和视频捕获。 对象检测(每个 Haar 分类器一个线程。) 使用检测结果增强输出并显示框架。 内存释放。

通过在所有线程之间共享每个捕获帧的内存,我获得了出色的性能和 CPU 利用率。

【讨论】:

以上是关于提高图像处理速度的主要内容,如果未能解决你的问题,请参考以下文章

处理上百万条的数据库如何提高处理查询速度

什么可以阻止多处理提高速度 - OpenMP?

如何提高google cloud vision api的处理速度?

sql处理百万级以上的数据提高查询速度的方法

处理大型数组时如何提高php的执行速度?

处理百万级以上的数据提高查询速度的方法