总体来说, 总共有三种办法:
(1) using 'at'
(2) using direct address calculation
(3) using 'ptr'
方法一:如下
Mat img= imread("image.jpg", 0) //0 for grayscale image reading
for (int i = 0; i < img.rows; i++) {// run through the rows
for(int j = 0; j < img.cols; j++) { // run through the cols
cout << (int) img.at<uchar>(i, j) << " "; // for getting
img.at<uchar>(i, j) = 0; // for setting
}
}
方法二: 对于grayscale image, by directly going to address.
Hint: 对于(8 bit)灰度图图像, 图像数据的存储格式如下所示, 5 x 10:
但是对于彩色图像而言, 例如彩色(RGB)图像有三通道, 在OpenCV 中尤其要注意彩色图像的存储格式是每一个像素是以GBR的顺序存储的。
要获得第(i, j)个pixel的 k 通道分量的数据, 计算公式如下:
对于灰度图像, 程序如下:
Mat img= imread("image.jpg", 0) //0 for grayscale image reading
for (int i = 0; i < img.rows; i++) {// run through the rows
for(int j = 0; j < img.cols; j++) { // run through the cols
cout << (int) *(img.data + img.step[0] * i + j * img.step[1]) << " "; // for getting
*(img.data + img.step[0] * i + j * imgstep[1]= 0; // for setting
}
}
对于彩色图像如下:
Mat img= imread("image.jpg", 1) //1 for color image reading
for(int k = 0; k < img.step[1]; k++) {
for (int i = 0; i < img.rows; i++) {// run through the rows
for(int j = 0; j < img.cols; j++) { // run through the cols
cout << (int) *(img.data + k + img.step[0] * i + j * img.step[1]) << " "; // for getting
*(img.data + k + img.step[0] * i + j * imgstep[1]= 0; // for setting
}
}
方法三, 使用指针
对于灰度图像:
Mat img= imread("image.jpg", 0) //0 for grayscale image reading
for (int i = 0; i < img.rows; i++) {// run through the rows
uchar* rowPtr = img.ptr<uchar>(i); // rowPtr holds the pointer to ith row
for(int j = 0; j < img.cols; j++) { // run through the cols
cout << (int) rowPtr[j] << " "; // for getting
rowPtr[j] = 0; // for setting
}
for(int i = 0; i < img -> height; i++) {
for(int j = j; j < img -> width; j++) {
cvScalar s;
s = cvGet2D(img, i, j);
s.val[0] = 0; //B
s.val[1] = 0; //G
s.val[2] = 0; //R
cvSet2D(img, i, j, s);
}
}
对于小的矩阵, 可以如下优化:
#include <opencv2/core/core.hpp>
using namespace cv;
int main(void)
{
Mat img = imread("test.jpg");
int rows = img.rows;
int cols = img.cols;
if (img.isContinuous())
{
cols = rows * cols; // Loop over all pixels as 1D array.
rows = 1;
}
for (int i = 0; i < rows; i++)
{
Vec3b *ptr = img.ptr<Vec3b>(i);
for (int j = 0; j < cols; j++)
{
Vec3b pixel = ptr[j];
}
}
return 0;
}
还可以如下: