OpenCV学习笔记4.0(4)Mat图像的灰度化和处理
原理
由于学习的深度,可能理解有不少偏差,在日后的学习中会逐渐修改。
在图像处理中最基础的知识点即使图像的像素点以及通道问题,彩色图片是处于色彩空间中的,色彩空间有许多种,例如RGB色彩空间和YUV色彩空间等等。
我们所见到的最多的是RGB图片,即由红绿蓝三通道叠加形成的图片,每一个通道在图片的像素点都有位于0-255 的像素值,叠加形成了不同的色彩。
但是,在图片处理的时候彩色图片的多通道增加了处理图像的繁琐程度,因此在处理图像时都会把图片进行灰度化处理,变成单通道图像。
灰度化处理
在opencv4.0中灰度化处理的函数出现了变化
划重点:在opencv3.1.0中可以使用的CV_BGR2GRAY函数在opencv4.0中不可使用
但是函数COLOR_BGR2GRAY仍然可用。
灰度化处理使用cvtColcor函数
cvtColor(src,gray_src,COLOR_BGR2GRAY);
src为原图,gray_src为灰度化处理过后的图片
对灰度化图片进行像素翻转处理
即是练习对于图像的像素点处理,将单通道图片的像素值变为(n-255)即对亮度进行翻转
其中gray_src.at< uchar >(row,col)函数可以的读取灰度化图像gray_src的像素点在(row,col)处的值
int height = gray_src.rows;
int width = gray_src.cols;
for (int row = 0,row < height; row++)
{
for(int col = 0,col < width ; col++)
{
int gary = gray_src.at<uchar>(row,col);
gary_src.at<uchar>(row,col) = 255 - gray;
}
}
以上的代码是先定义并赋值灰度化图像的像素的行数rows和列数cols,通过row和col的嵌套if循环语句到达图像中的每一个像素点,通过指针得到该点的像素值,通过中间变量gray,进行运算将该点的像素值转化为(n-255)最后再赋给该点的像素点,最后得到翻转后的图像。
多通道图像的像素点值的改变
读取RGB图像的像素值函数
img.at<Vec3b>(y,x)[0] = 128 //blue
img.at<Vec3b>(y,x)[1] = 128 //green
img.at<Vec3b>(y,x)[2] = 128 //red
Mat dst;
dst.create(src.size(), src.type());
height = src.rows;
width = src.cols;
int nc = src.channels();
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
if(nc == 1)
{
int gray = gray_src.at<uchar>(row, col);
gray_src.at<uchar>(row, col) = 255 - gray;
}
else if (nc == 3)
{
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
/*
dst.at<Vec3b>(row, col)[0] = 255 - b;
dst.at<Vec3b>(row, col)[1] = 255 - g;
dst.at<Vec3b>(row, col)[2] = 255 - r;
*/
dst.at<Vec3b>(row, col)[0] = 0;
dst.at<Vec3b>(row, col)[1] = g;
dst.at<Vec3b>(row, col)[2] = r;
gray_src.at<uchar>(row, col) = min(r, min(b, g));
}
}
}
如上代码的同样是利用if的嵌套使用到达bgr图像的像素点位置
定义中间变量b,g,r利用 src.at< Vec3b >(row,col)[0]函数提取出该点的三个通道的像素值
通过赋值给与图像新的像素值。
其实在实际操作中可以发现如果只调整单个通道的像素值就好像跟图像加入了单色的滤镜,非常实用。
其中还出现了gary_src.at< uchar >(row,col) = min(r,min(b,g))语句
是在if的嵌套循环获取彩色图像的每一个像素点值然后变为灰度图像的像素点
其中的min函数还有其对应的max函数都可以将彩色图片的像素值转换为灰度图像的像素值
在实际操作后能发现min函数产生的灰度图像亮度明显小于max函数产生的灰度图像
本次学习所使用的代码:
#include <opencv2/opencv.hpp>
#include<iostream>;
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src, gray_src;
src = imread("E://text//text.jpg");
if (src.empty())
{
cout<< "could not load image..." << endl;
return -1;
}
imshow("the primary image", src);
cvtColor(src, gray_src, COLOR_BGR2GRAY);
imshow("output", gray_src);
int height = gray_src.rows;
int width = gray_src.cols;
//单通道
for (int row = 0; row < height; row++)
{
for(int col =0;col < width;col++)
{
int gray = gray_src.at<uchar>(row, col);
gray_src.at<uchar>(row, col) = 255 - gray;
}
}
Mat dst;
dst.create(src.size(), src.type());
height = src.rows;
width = src.cols;
int nc = src.channels();
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
if (nc == 1)
{
int gray = gray_src.at<uchar>(row, col);
gray_src.at<uchar>(row, col) = 255 - gray
}
else if (nc == 3)
{
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2;
/*
dst.at<Vec3b>(row, col)[0] = 255 - b;
dst.at<Vec3b>(row, col)[1] = 255 - g;
dst.at<Vec3b>(row, col)[2] = 255 - r;
*/
dst.at<Vec3b>(row, col)[0] = 0;
dst.at<Vec3b>(row, col)[1] = g;
dst.at<Vec3b>(row, col)[2] = r;
gray_src.at<uchar>(row, col) = min(r, min(b, g));
}
}
}
//bitwise_not(src, dst);
//imshow("the rbg invert", dst);
imshow("gray invert", gray_src);
waitKey(0);
return 0;
}