我想知道在OpenCV中使用Mat访问数据的方式。如您所知,我们可以通过多种方式访问数据。我想在Mat中存储图像(宽度x高度x 1深度)并循环访问图像中的每个像素。使用ptr<>(irow)获取行像素然后访问行中的每一列是最好的方法吗?或者在<>(irow,jcol)使用是最好的?或者使用index = irow直接计算索引*宽度+ jrow是最好的?任何人都知道原因。
提前致谢
答案 0 :(得分:3)
您可以在文档中找到相关信息:the basic image container和how to scan images。
如果您对OpenCV或C语言类型没有经验,我建议您使用at
(here)练习。但最快的方式是ptr
为Nolwenn 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.);
}