【发布时间】:2021-08-05 13:52:04
【问题描述】:
OpenCV中的就地RGB->BGR颜色转换例程是否节省了一些内存,但需要更长的时间?如果是,谁能解释为什么?
我的应用程序调用 OpenCV(4.2.0 版)中的 cv::cvtColor(srcMat, dstMat, cv::COLOR_RGB2BGR) 例程。为了使应用程序更快,我尝试了该例程的就地版本(通过使用相同的 Mat 对象来调用源和目标)。我预计速度会略有提高,因为就地版本不会分配新内存。
为了测试我的预期,我在 10,000 个 250x250 RGB 图像上循环运行我的应用程序。令我惊讶的是,当使用就地版本时,我的应用程序变慢了。其实我看到图片越大(500x500 vs 250x250),in-place 版和普通版的差别就越大。
这是预期的吗?如果是这样,是不是因为in-place版本做了一个swap操作(更多语句),而普通版本只是一个copy操作?
有人愿意尝试重现这种行为吗?通过以 2 种不同的方式对以下 sn-p 进行计时,可以轻松完成:1) 使用下面的 sn-p,以及 2) 按照 sn-p 中 cmets 中的简要说明进行就地版本。
// Read image
Mat srcMat = imread(filename);
// Comment out this line for the in-place version
Mat dstMat;
for (int i=0; i<10000; i++)
{
// Use srcMat instead of dstMat in the in-place version
cv::cvtColor(srcMat, dstMat, cv::COLOR_RGB2BGR);
}
谢谢。
【问题讨论】:
-
您在哪个 CPU 上遇到此问题,甚至可能是操作系统?您使用的是哪种 OpenCV 版本? |好问题,但很难回答。
-
CPU:Intel(R) Xeon(R) CPU E5-2450 v2 @ 2.50GHz。它有 16 个超线程内核。我的应用程序运行 32 个线程,每个(并行)线程处理一个图像。操作系统:Unix。使用 ICC 编译器优化 OpenCV 构建。
-
我猜这是某种处理循环中的操作。在这种情况下,我只需要一个在迭代中持续存在的
Mat,而不是就地执行它,并将其用作cvtColor的目的地。只要目标具有正确的数据类型和大小,它就不会被重新分配。通常是这种情况,额外的内存不太可能是关键的。 |哦,其中 32 个并行,我想在那种情况下它可能更重要:) -
由于loop carried dependencies,就地处理阻止了一些编译(和执行)优化。我不能说这就是这里的解释,但它可能是。
-
@DanMašek 接下来,我现在尝试了一个在迭代中持续存在的目标矩阵。这个新版本的性能比 in-place 版本好(srcMat 和 dstMat 相同),但仍然比普通版本稍差。我仍在调查这一切,但到目前为止,似乎不为目标矩阵分配内存并没有提高性能。
标签: performance opencv memory in-place