OpenCV4.0(4)Mat图像的灰度化和处理

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;

}

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狗头狗不狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值