OpenCV Mat array access, which way is the fastest for and why?
Asked Answered
I

4

6

I am wondering about the way of accessing data in Mat in OpenCV. As you know, we can access to get data in many ways. I want to store image (Width x Height x 1-depth) in Mat and looping access each pixel in the image. Using ptr<>(irow) to get row-pixel and then access each column in the row is the best way? or using at<>(irow,jcol) is the best? or using directly calculate the index by using index = irow*Width + jrow is the best? Anyone know the reason.

Thanks in advance

Ibrahim answered 11/1, 2013 at 11:51 Comment(0)
A
4

You can find information here in the documentation: the basic image container and how to scan images.

I advice you to practice with at (here) if you are not experienced with OpenCV or with C language types hell. But the fastest way is ptr as Nolwenn answer because you avoid the type checking.

Appendectomy answered 11/1, 2013 at 12:15 Comment(0)
C
3

at<T> does a range check at every call, thus making it slower than ptr<T>, but safer.

So, if you're confident that your range calculations are correct and you want the best possible speed, use ptr<T>.

Cottage answered 11/1, 2013 at 12:3 Comment(0)
C
3

I realize this is an old question, but I think the current answers are somehow misleading.

Calling both at<T>(...) and ptr<T>(...) will check the boundaries in the debug mode. If the _DEBUG macro is not defined, they will basically calculate y * width + x and give you either the pointer to the data or the data itself. So using at<T>(...) in release mode is equivalent to calculating the pointer yourself, but safer because calculating the pointer is not just y * width + x if the matrix is just a sub-view of another matrix. In debug mode, you get the safety checks.

I think the best way is to process the image row-by-row, getting the row pointer using ptr<T>(y) and then using p[x]. This has the benefit that you don't have to count with various data layouts and still plain pointer for the inner loop.

You can use plain pointers all the way, which would be most efficient because you avoid one the multiplication per row, but then you need to use step1(i) to advance the pointer. I think that using ptr<T>(y) is a nice trade-off.

Champlin answered 12/12, 2014 at 18:51 Comment(0)
N
3

According to the official documentations, they suggest that the most efficient way is to get the pointer to the row first, and then just use the plain C operator []. It also saves a multiplication for each iteration.

// 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.);
}
Neoplasticism answered 7/5, 2015 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.