Pergunta

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.

Foi útil?

Solução

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;
    }
} 

Outras dicas

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]);
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top