Как редактировать/считывать значения пикселей в OpenCv из переменной Mat?

Я ищу эффективный способ редактирования/чтения пикселей из переменной Mat (или Mat3b).

Я использовал: -

Image.at<Vec3b>(i,j)

но он кажется очень медленным.

Я также использовал это: -

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

но проблема, с которой я столкнулась, - это когда я запускаю этот цикл

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

только часть изображения почернела.

Ответы

Ответ 1

Здесь вы можете увидеть некоторые из возможностей быстрого доступа к элементу.

Но если вы хотите сделать это по-своему, вам нужно добавить скобку. В противном случае вы неверно вычисляете индексы:

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

Но макет памяти не гарантированно будет смежным из-за заполнения. Итак, согласно 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;
    }
} 

Ответ 2

Это один из наиболее эффективных способов редактирования/чтения пикселей из cv:: Mat. Создайте указатель на строку (если требуется конкретный канал)

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