欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【opencv4.3.0教程】07之像素基本操作 2 读写像素

程序员文章站 2022-07-07 13:38:57
...

目录

一、前言

二、温故知新——像素基本操作

1、获取像素指针

1.灰度图

2.彩色图像

2、像素范围处理

三、读写像素

1、读像素

2、写像素

四、代码实战


一、前言

从上一篇文章开始,我们走进了像素操作的世界,然后我们讲解了最基本的像素操作,为什么是最基本的呢?

我们做像素操作,无非就是获取到像素,然后修改像素,然后展示效果。这些步骤里面,都需要通过像素指针去进行操作,然后操作过程中,要保证像素范围是在合法区域的。也就是不管什么操作,都需要基于我们昨天讲的两个最基本操作。

今天我们要讲的是读写像素,就是在获取到图像像素指针之后的两个基本操作。让我们一起,复习一下上一篇文章讲的基本操作,然后一起走进今天的内容吧!

二、温故知新——像素基本操作

1、获取像素指针

获取像素指针包括获取灰度图像像素指针和彩色图像像素指针。

1.灰度图

对于灰度图,我们有如下两种方式获取像素指针:

一种是以行列坐标访问,前面是行,后面是列;

一种是以点坐标访问,前面是x轴,后面是y轴;

src_gray.at<uchar>(y, x); //行在前,列在后,y表示行,x表示列
src_gray.at<uchar>(Point(x, y));

 

2.彩色图像

对于彩色图像,我们要使用一个类型Vec3b来获取三个通道的数值,然后分别赋给三个整型变量,或者直接赋值给Scalar类型数据:

	Vec3b BGR = src.at<Vec3b>(row, col);
	int B = BGR.val[0];
	int G = BGR.val[1];
	int R = BGR.val[2];
	Scalar BGR1 = src.at<Vec3b>(Point(col, row));

 

2、像素范围处理

然后我们需要考虑像素范围是0-255,所以我们要控制像素范围,在OpenCV中,我们使用下面的API来控制范围,遵循的原则如下:

小于0,返回值为0;

大于255,返回值为255;

其他,返回其本身。

saturate_cast<uchar>(number);

 

三、读写像素

1、读像素

读像素比较简单,其实我们在讲获取像素指针的时候,就不可避免的要涉及到读像素。因为只有我们定义的像素指针成功读取到像素,我们才能知道我们定义的像素指针是没有问题的。所以我们在讲像素指针的实战时候,其实就是在读像素。

读像素的操作包括如下:

1.加载图像;

2.使用像素指针获取像素;

3.获取每个通道的值;

对于灰度图像来说,因为只有一个通道,我们可以将最后两步合并,直接将像素指针的值赋给int类型的数据就获取到了通道的值。

2、写像素

当我们可以读取到像素的时候,那我们最先能想到的操作应该就是修改像素了吧。

写像素是像素操作中最基本的操作,就是通过赋值的方式直接修改像素值。

//灰度图像
image.at<uchar>(y, x) = 123;  
 
//彩色图像
image.at<Vec3b>(y,x)[0]=0; // blue
image.at<Vec3b>(y,x)[1]=0; // green
image.at<Vec3b>(y,x)[2]=255; // red

当然,如果我们想修改一幅图像上的全部像素值,我们还可以选择一个更为直接的方法,使用Scalar直接修改图像的全部像素颜色。

src = Scalar(0, 0, 255);

 

四、代码实战

为了方便大家对上面知识有更加深刻的理解,我们通过一个实例来感受一下:

我们对一幅彩色图像的像素进行读取和修改,看一下他们的效果:

Mat src = imread("./image/sign.png");
	if (!src.data)
	{
		cout << "ERROR : could not load image.\n";
		return -1;
	}
	imshow("init_src", src);
	//读像素
	for (int i = 0; i < src.rows; i+= src.rows/5)
	{
		for (int j = 0; j < src.cols; j+= src.cols / 5)
		{
			Vec3b BGR = src.at<Vec3b>(i, j);
			int B = BGR.val[0];
			int G = BGR.val[1];
			int R = BGR.val[2];	
			cout << "[" << B << ", " << G << ", " << R << "]\t";
		}
		cout << endl;
	}
        //写像素
	for (int i = 0; i < src.rows; i += 5)
	{
		for (int j = 0; j < src.cols; j += 5)
		{
			src.at<Vec3b>(i, j)[0] = 0;
			src.at<Vec3b>(i, j)[1];
			src.at<Vec3b>(i, j)[2] = 0;
		}
	}
	
	imshow("new_src", src);

【opencv4.3.0教程】07之像素基本操作 2 读写像素

如果我们修改第一通道和第三通道的像素值,图片就会如下所示(隔点修改像素值):

【opencv4.3.0教程】07之像素基本操作 2 读写像素
图上出现一些密密麻麻的小点

如果我们图片上的全部像素值修改:

	//写像素
	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			src.at<Vec3b>(i, j)[0];
			src.at<Vec3b>(i, j)[1] = 0;
			src.at<Vec3b>(i, j)[2] = 0;
		}
	}

那我们得到的图片是:

【opencv4.3.0教程】07之像素基本操作 2 读写像素

 

大家也可以自己随心修改一些像素值看一下效果呀!