提高图像处理速度

时间:2012-01-27 20:12:22

标签: c++ multithreading image-processing opencv

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

除了更改处理算法(假设,现在,您无法更改它)。我是否应该采取任何措施来最大限度地提高处理速度?

我想也许多线程可以在这里提供帮助,但我很惭愧地说我真的不知道这些细节(尽管很明显我之前使用过多线程而不是C ++)。

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

多线程会帮助吗?

是否有任何提示,特别是提高OpenCV的速度,或者我可能陷入降低速度的任何陷阱。

感谢。

6 个答案:

答案 0 :(得分:6)

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

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

这可能会使您当前(调试的)算法几乎保持不变,但是需要更多的内存来缓冲中间结果。

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

答案 1 :(得分:5)

有一个重要的事情是提高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中突出显示标题作为一种重要而有效的编码工具非常重要。

答案 2 :(得分:4)

  

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

是的,虽然它在很大程度上取决于所使用的特定算法,以及您编写线程代码来处理同步等事务的技巧。你没有真正提供足够的细节来做出更好的评估。

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

for (i=0; i < DATA_SIZE; i++)
{
   output[i] = f(input[i]);
}

用于某些功能f。这些被称为令人难以置信的可并行化;您可以简单地将数据拆分为N个块,并让N个线程单独处理每个块。像OpenMP这样的库使得这种线程非常简单。

答案 3 :(得分:3)

除非您使用的特定算法已针对多线程/并行平台进行了优化,否则将其丢弃到x-core处理器将不会对您有任何帮助。该算法必须具有固有的线程,以便从多个线程中受益。但如果没有考虑到这一点,就必须改变它。另一方面,至少在概念上,许多图像处理算法是“令人难以置信的并行”。你能分享一下你想到的算法的更多细节吗?

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

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

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

  1. 帧内存和视频捕获的分配。
  2. 对象检测(每个Haar分类器一个线程。)
  3. 使用检测结果增加输出并显示帧。
  4. 内存释放。
  5. 对于在所有线程之间共享的每个捕获帧的内存,我获得了很好的性能和CPU利用率。