Question

I am looking for an efficient way for editing/reading pixels from Mat (or Mat3b) variable.

I have used :-

Image.at<Vec3b>(i,j)

but it seems to be very slow.

I also used this:-

A.data[A.channels()*A.cols*i + j + 0]

but the problem I am facing with this is when I run this loop

for(i=0; j<A.rows; i++){
   for(j=0; j<A.cols; j++){
           A.data[A.channels()*A.cols*i + j + 0] = 0;
           A.data[A.channels()*A.cols*i + j + 1] = 0;
           A.data[A.channels()*A.cols*i + j + 2] = 0;
    }
} 

only a portion of image is blackened.

Was it helpful?

Solution

Here you can see some of the possibilities for fast element access.

But if you want to do it your way, you need to add a bracket. Otherwise you index computation is not correct:

for(int i=0; i<A.rows; i++){
   for(int j=0; j<A.cols; j++){
           A.data[A.channels()*(A.cols*i + j) + 0] = 0;
           A.data[A.channels()*(A.cols*i + j) + 1] = 0;
           A.data[A.channels()*(A.cols*i + j) + 2] = 0;
    }
} 

But the layout of the memory is not guaranteed to be contiguous due to padding. So according to this you should rather use a formula like this:

for(int i=0; i<A.rows; i++){
   for(int j=0; j<A.cols; j++){
           A.data[A.step[0]*i + A.step[1]* j + 0] = 0;
           A.data[A.step[0]*i + A.step[1]* j + 1] = 0;
           A.data[A.step[0]*i + A.step[1]* j + 2] = 0;
    }
} 

OTHER TIPS

This is one of the most efficient way for editing/reading pixels from cv::Mat. Create pointer to a row (of specific channel if needed)

for(int i=0; i<A.rows;i++){
  uchar* rowi = A.ptr/*<uchar>*/(i);
  for(int j=0; j<A.cols; j++){
     doProcessOnPixel(rowi[j]);
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top