OpenCV Mat数组访问,哪种方式最快,为什么?

时间:2013-01-11 11:51:49

标签: c++ image image-processing opencv mat

我想知道在OpenCV中使用Mat访问数据的方式。如您所知,我们可以通过多种方式访问​​数据。我想在Mat中存储图像(宽度x高度x 1深度)并循环访问图像中的每个像素。使用ptr<>(irow)获取行像素然后访问行中的每一列是最好的方法吗?或者在<>(irow,jcol)使用是最好的?或者使用index = irow直接计算索引*宽度+ jrow是最好的?任何人都知道原因。

提前致谢

4 个答案:

答案 0 :(得分:3)

您可以在文档中找到相关信息:the basic image containerhow to scan images

如果您对OpenCV或C语言类型没有经验,我建议您使用athere)练习。但最快的方式是ptrNolwenn answer,因为您可以避免类型检查。

答案 1 :(得分:3)

我意识到这是一个老问题,但我认为目前的答案有些误导。

同时调用at<T>(...)ptr<T>(...)将检查调试模式中的边界。如果未定义_DEBUG宏,它们将基本计算y * width + x,并为您提供指向数据的指针或数据本身。因此在释放模式下使用at<T>(...)等同于自己计算指针,但更安全,因为如果矩阵只是另一个矩阵的子视图,计算指针不仅仅是y * width + x。在调试模式下,您将获得安全检查。

我认为最好的方法是逐行处理图像,使用ptr<T>(y)获取行指针,然后使用p[x]。这样做的好处是您不必使用各种数据布局和内部循环的普通指针。

你可以一直使用普通指针,这将是最有效的,因为你避免每行乘法,但是你需要使用step1(i)来推进指针。我认为使用ptr<T>(y)是一个很好的权衡。

答案 2 :(得分:2)

at<T>会在每次通话时进行范围检查,从而使其慢于ptr<T>,但更安全。

因此,如果您确信范围计算正确并且您希望获得最佳速度,请使用ptr<T>

答案 3 :(得分:2)

根据官方文档,他们建议最有效的方法是首先获取指向行的指针,然后只使用普通的C运算符[]。它还为每次迭代保存了一个乘法。

// compute sum of positive matrix elements
// (assuming that M isa double-precision matrix)
double sum=0;
for(int i = 0; i < M.rows; i++)
{
    const double* Mi = M.ptr<double>(i);
    for(int j = 0; j < M.cols; j++)
        sum += std::max(Mi[j], 0.);
}