我正在使用C ++和OpenCV来实时处理从网络摄像头拍摄的一些图像,我希望从我的系统中获得最佳速度。
除了更改处理算法(假设,现在,您无法更改它)。我是否应该采取任何措施来最大限度地提高处理速度?
我想也许多线程可以在这里提供帮助,但我很惭愧地说我真的不知道这些细节(尽管很明显我之前使用过多线程而不是C ++)。
假设我有一个x-core处理器,将处理拆分成x个线程实际上会加快速度吗?...或者假设我正在寻找20fps的吞吐量,这些线程的管理开销会否定它(我假设这将影响你给出的答案,因为它应该告诉你每个线程将完成多少处理)
多线程会帮助吗?
是否有任何提示,特别是提高OpenCV的速度,或者我可能陷入降低速度的任何陷阱。
感谢。
答案 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
程序基本上是一个并行算法,可以在多个线程之间分配任务,每个任务都有一个单独的流水线线程:
对于在所有线程之间共享的每个捕获帧的内存,我获得了很好的性能和CPU利用率。