Как редактировать / читать значения пикселей в OpenCv из переменной Mat? - PullRequest
14 голосов
/ 02 апреля 2012

Я ищу эффективный способ редактирования / чтения пикселей из переменной 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;
    }
} 

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

Ответы [ 2 ]

19 голосов
/ 02 апреля 2012

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

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

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;
    }
} 
14 голосов
/ 02 апреля 2012

Это один из наиболее эффективных способов редактирования / чтения пикселей из 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]);
  }
}
...