Mat
赋值和创建:
Mat A = imread("images/test.png");
Mat B=A;赋值
Mat C=A.clone(); 克隆
Mat D;
A.copyTo(D);复制
// 创建空白图像
Mat E= Mat::zeros(A.size(), A.type()); 创建矩阵
Mat F = Mat::zeros(Size(512, 512), CV_8UC3);8位3通道
Mat G= Mat::ones(Size(512, 512), CV_8UC3);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0,
0, -1, 0,
0, -1, 0);
创建了一个3X3的矩阵
0 -1 0
0 -1 0
0 -1 0
像素级操作方式
因为Mat本质就是矩阵 所以可以通过循环来进行读取每个点的像素值进行操作
int height = src.rows; 获取图像的列
int width = src.cols;获取图像的行
int ch = src.channels();图像的通道数
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
//通过行列来进行循环读取每个像素的值
if (ch == 3) {
//如果是三通道图像
Vec3b bgr = src.at<Vec3b>(row, col);
bgr[0] = 255 - bgr[0];
bgr[1] = 255 - bgr[1];
bgr[2] = 255 - bgr[2];
src.at<Vec3b>(row, col) = bgr;
完成反转图像操作
}
else if (ch == 1) {
//如果是单通道图像
int gray = src.at<uchar>(row, col);
src.at<uchar>(row, col) = 255 - gray;
}}}
Vec3b 通过查询定义可以知道 其定义
typedef Vec<uchar, 3> Vec3b;
其实这句就是定义一个uchar类型的数组,长度为3而已
那么三通道(RGB)实际存储的是方式是BGRsrc图像(x,y) 这一点的像素可以表示为
B通道值为bgr[0]
G通道值为bgr[1]
R通道值为bgr[2]
通过迭代器进行操作
Mat src;
Mat_<Vec3b>::iterator it = src.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = src.end<Vec3b>();
//创建两个迭代器表示图像的开头和结尾
for(;it != itend;it++)
{
(*it)[0] = 255-(*it)[0];
(*it)[1] = 255(*it)[1];
(*it)[2] =255- (*it)[2];
}
通过指针进行操作
Mat src;
Mat result = Mat::zeros(src.size(), src.type());
int blue = 0, green = 0, red = 0;
int gray;
for (int row = 0; row < height; row++) {
//循环遍历每一列
uchar* curr_row = src.ptr<uchar>(row);
uchar* result_row = result.ptr<uchar>(row);
//curr_row 表示的是src图像第row列数据的头指针
//result_row 表示的是result_row 图像第row列数据的头指针
for (int col = 0; col < width; col++) {
if (ch == 3) {
blue = *curr_row++;
green = *curr_row++;
red = *curr_row++;
//图像存储 BGR BGR BGR
//*curr_row=B *curr_row++=G 再次加就是R 如此循环
*result_row++ =255- blue;
*result_row++ = 255-green;
*result_row++ = 255-red;
}
else if (ch == 1) {
gray = *curr_row++;
*result_row++ = 255-gray;
}
}
}
这篇博客回顾了OpenCV中的Mat类,探讨了如何进行像素级的颜色反转操作。文章详细介绍了通过Vec3b理解像素结构,以及利用迭代器和指针两种方式遍历并修改Mat矩阵中的像素值。

7万+

被折叠的 条评论
为什么被折叠?



