操作像素(一)--存取像素值

  为了编写计算机视觉应用,你必须会存取图像的内容,如修改或者创建图像。本章将教会你如何操作图像的基本元素,即所谓的像素。从根本上来说,一张图像是一个有数值组成的矩阵。这也是OpenCV 2用 cv :: Mat 这个数据结构来表示图像的原因。矩阵的每一个元素代表一个像素。对于灰度图像(仅包含“灰色”的图像)而言,像素由8位无符号数来表示,其中0代表黑色,255代表白色。对于彩色而言,每个像素需要三个这样的8位无符号数来表示三个颜色通道(红、绿、蓝)。因此,再这中情况下,矩阵的元素是一个三元数。

  我们通过一个简单的函数来演示如何直接存取像素值。该函数会在图像中加入椒盐噪点。椒盐噪点是一种特殊的噪点,顾名思义,它随机地件该部分像素设置为白色或者为黑色。在传输过程中,如果部分像素值丢失,那么这种噪点就会出现。在我们的例子中,我们随机挑选若干个像素,并将他设为白色。

实现方法

  我们创建一个函数,它的第一个参数就是一张输入图像,该函数会修改此图片。为达到这个目的,我们需要使用传引用的参数传递方式。这个函数的第二个参数是我们欲将其替换成白色相数点个数:

void salt(Mat &image, int n){
	for (int k = 0; k < n; k++)
	{
		int i = rand() % image.cols;
		int j = rand() % image.rows;
		if (image.channels() == 1)//灰度图
		{
			image.at<uchar>(j, i) = 225;
		}
		else if (image.channels() == 3)//彩色图
		{
			image.at<Vec3b>(j, i)[0] = 255;
			image.at<Vec3b>(j, i)[1] = 255;
			image.at<Vec3b>(j, i)[2] = 255;
		}
		

		
	}
}


  这个函数有一个单层循环构成。每次循环将一个随机选取的像素的值设置为255。随机选取的像素的行号i和列号j是通过一个随机函数得到的。此处我们通过检查图像的通道数来区分灰度图像和彩色图像。对于灰度图像,我们可以直接将像素值设为255。对于彩色图像,我们需要将每个通道的值都设置为255才能得到一个白色像素。

  你可以先打开一个图像,然后将在调用这个函数时候传递给它。

int main()
{
	Mat image = imread("girl.jpg");
	salt(image, 3000);
	namedWindow("随机白点");
	imshow("随机白点", image);
	waitKey();
}

处理前图片:



处理后的图片



作用原理

  类cv::Mat 有若干个成员函数可以获取图像的属性。公有成员变量cols和rows给出了图像的宽和高。成员函数at(int y,int x)用来存取图像的元素。但是必须在编译期知道图像的数据类型,因为cv::Mat可以存放任意数据累心的元素。这也是这个元素用模板函数来实现的原因。也就是意味着,当调用该函数时,你需要使用一下方式指定数据类型:

  image.at<uchar>(j,i)=255;

   对于彩色图像,每个像素有三部分构成:红色通道、绿色通道、蓝色通道。因此,一个包含彩色图像的cv::Mat 会返回一个由三个8位数组成的向量。OpenCV将此类向量定义为cv:: Vec3b ,即由三个unsigned char 组成的向量。这也解释了为什么存取彩色图像像素的代码可以写成以下形式:

  image.at<cv::Vec3b>(j,i)[chanbel]=value;

  其中,索引值channel表明了颜色通道号。

  注意:一定要确保指定的数据类型要和矩阵中的数据类型相符合。at方法本身不会进行任何数据类型的装换。

  类似地,OpenCV还有二元速向量类型和四元素类型(CV::Vec2b 和CV::Vec4b )。OpenCV同样拥有针对其他数据类型的向量类型,如s代表short,i代表int,f代表float,d代表double。所有的这些类型都是使用模板类cv::Vect<T,N>定义的,其中T代表类型,N代表元素个数。

 扩展阅读

 cv:: Mat_  ...


cv::Mat_<uchar> im2=image;//im2指向image

im2(50,100)=0;//存取第50行,100列


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值