遍历方式有很多种,下面给出两种方式:
- 基于数组遍历
- 基于指针遍历
1、基于数组遍历
Mat类中的cols、rows为图像的宽、高。成员函数at(row,col)可以存取图像元素。对于包含彩色图像的Mat,OpenCV中将三个8位数组组成的向量定义为Vec3b。
访问彩色图像像素的一般形式:
image.at<Vec3b>(j, i)[channel] = value;
程序演示:
#include<opencv2/opencv.hpp>
#include<iostream>using namespace cv;
using namespace std;int main(int argc, char** argv) {Mat src = imread("D:/VC2017_WORKSPACE/Images/dog.jpg", IMREAD_COLOR);if (src.empty()) {printf("could not find image file");return -1;}namedWindow("demo-002", WINDOW_FREERATIO);imshow("demo-002", src);//获取图像的宽度、高度、通道数int width = src.cols;int height = src.rows;int dim = src.channels();//像素遍历for (int row = 0; row < height; row++) {for (int col = 0; col < width; col++) {if (dim == 3) {//彩色图像遍历Vec3b pixel = src.at<Vec3b>(row, col);int blue = pixel[0];int green = pixel[1];int red = pixel[2];//取反src.at<Vec3b>(row, col)[0] = 255 - blue;src.at<Vec3b>(row, col)[1] = 255 - green;src.at<Vec3b>(row, col)[2] = 255 - red;}if (dim == 1) {//灰度图像遍历uchar pv = src.at<uchar>(row, col);//取反src.at<uchar>(row, col) = (255 - pv);}}}namedWindow("pixel-demo", WINDOW_FREERATIO);imshow("pixel-demo", src);waitKey(0);destroyAllWindows();return 0;
}
显示结果:

2、基于指针遍历
Mat类提供了ptr函数可以得到图像任意行的首地址。ptr是一个模板函数,返回值为第i行的首地址,一般形式如下:
uchar* data = image.ptr<uchar>(i);
程序演示:
#include<opencv2/opencv.hpp>
#include<iostream>using namespace cv;
using namespace std;int main(int argc, char** argv) {Mat src = imread("D:/VC2017_WORKSPACE/Images/dog.jpg", IMREAD_COLOR);if (src.empty()) {printf("could not find image file");return -1;}namedWindow("原图", WINDOW_FREERATIO);imshow("原图", src);//获取图像的宽度、高度、通道数int width = src.cols;int height = src.rows;int dim = src.channels();//像素遍历Mat result = Mat::zeros(src.size(), src.type());//后面用来观察遍历结果,作对比for (int row = 0; row < height; row++) {uchar* curr_row = src.ptr<uchar>(row);//获取当前行的指针uchar* result_row = result.ptr<uchar>(row);//获取result图像的行指针for (int col = 0; col < width; col++) {if (dim == 3) {//彩色图像遍历int blue = *curr_row++;int green = *curr_row++;int red = *curr_row++;//访问的每个通道的像素赋值给result*result_row++ = blue;*result_row++ = green;*result_row++ = red;}if (dim == 1) {//灰度图像遍历int pv = *curr_row++;*result_row++ = pv;}}}namedWindow("原图像素遍历后赋值给result的结果", WINDOW_FREERATIO);imshow("原图像素遍历后赋值给result的结果", result);waitKey(0);destroyAllWindows();return 0;
}
效果显示:



















