如何从Mat变量中编辑/读取OpenCv中的像素值?

14

我希望找到一种高效的方法来编辑/读取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;
    }
} 

图片只有一部分变黑了。


有更快的访问Mat元素的方法,正如被接受的答案所正确说明的那样,但在Release模式下运行程序将大大加速mat.at<Vec>()的访问。它们只会比指针访问稍微慢一点。 - Sam
2个回答

19

这里可以看到一些快速访问元素的可能性。

但是如果您想按照自己的方式进行操作,您需要添加一个括号。否则,索引计算将不正确:

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

但是由于填充,内存的布局不能保证连续。

因此,根据这里的建议,你应该使用类似这样的公式:

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

A.data[A.step[0]i + A.step[1] j + 0] = 0; 这行代码出错了。 - Ravi Upadhyay
2
我使用了A.data[A.step*i + A.channels()*j + 0],这个方法运行得很好。谢谢,它比之前的方法节省了很多时间。 :) - Ravi Upadhyay

14

这是一种编辑/读取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]);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接