Ask Your Question

What is the most effective way to access cv::Mat elements in a loop?

asked 2012-06-27 11:11:21 -0500

Maria Dimashova gravatar image

updated 2015-08-24 13:16:04 -0500

I need to process cv::Mat elements and there is not special OpenCV function that performs my task. So I have to iterate the elements in loop. What is the more effective way of elementwise access? cv::Mat iterators, cv::Mat::at() method, maybe pointer arithmetic by hand or something else?

edit retag flag offensive close merge delete

5 answers

Sort by ยป oldest newest most voted

answered 2012-06-27 12:40:46 -0500

If you really care about efficiency then pointer access is the most efficient. However, I suggest you to use it only in time-critical parts of your program because readability and safety is more important in other case.

See the OpenCV tutorial on this topic for details.

edit flag offensive delete link more

answered 2014-09-24 11:11:14 -0500

lvv gravatar image

updated 2014-09-25 12:02:22 -0500

You probably will get x10 speedup by switching order of your for loops. First loop rows, than (inner) loop columns.

edit flag offensive delete link more

answered 2015-05-07 03:11:21 -0500

beahacker gravatar image

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.);
edit flag offensive delete link more

answered 2013-02-13 20:00:09 -0500

xaffeine gravatar image

jayrambhia's answer is approximately right, but it doesn't account for the step (also called the stride or pitch) of the Mat. You need to multiply by img.step, rather than img.cols. Also, if you're interested in speed, you want the per-colum loop nested inside the per-row loop. Something like the following. Even this assumes RGB color model in BGR component order, so it doesn't work for gray scale.

unsigned char *input = (unsigned char*)(;
for(int j = 0;j < img.rows;j++){
    for(int i = 0;i < img.cols;i++){
        unsigned char b = input[img.step * j + i ] ;
        unsigned char g = input[img.step * j + i + 1];
        unsigned char r = input[img.step * j + i + 2];


edit flag offensive delete link more


Using img.step for the stepsize did not work for me with a float-type matrix (openCV type CV_32FC1). I used img.cols instead and everything worked fine.

jshtok gravatar imagejshtok ( 2015-04-28 01:16:49 -0500 )edit

you need to multiply i with the number of channels too... unsigned char r = input[img.step * j + i*img.channels() + 2 ] ; etc

BoozeAddict gravatar imageBoozeAddict ( 2017-01-09 09:56:46 -0500 )edit

Important!!! The answer should be edited if possible

Croolman gravatar imageCroolman ( 2017-02-28 15:17:50 -0500 )edit

answered 2012-06-27 13:52:01 -0500

I'd say accessing it's data pointer.

Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR);
unsigned char *input = (unsigned char*)(;

int i,j,r,g,b;
for(int i = 0;i < img.cols;i++){
    for(int j = 0;j < img.rows;j++){
        b = input[img.cols * j + i ] ;
        g = input[img.cols * j + i + 1];
        r = input[img.cols * j + i + 2];
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2012-06-27 11:11:21 -0500

Seen: 72,933 times

Last updated: Sep 25 '14