OpenCV4学习笔记(5)——提取色彩区域及像素统计

本次要整理记录的内容有:通过HSV色彩空间提取具有某种色彩范围的区域和像素统计。

  1. HSV色彩空间提取色彩范围
    一般我们所使用的图像都是RGB图像,也就是具有R、G、B三通道的图像,每个通道的取值范围为[ 0 , 255 ]。而HSV图像同样是应用十分广泛的一种图像类型,它分为H、S、V三个通道,分别为色调、饱和度、亮度,其中H的取值范围是[ 0, 180 ],S和V的取值范围是[ 0 , 255 ]。因为HSV图像存在色调这一通道,而不同颜色的色调都是不同的,所以我们可以通过规定色调通道的不同取值范围从而来提取出不同的颜色。相应代码如下:
	/********************色彩空间  ---  提取色彩范围	********************/
	Mat image_RGB;
	image_RGB = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\greenback.png");
	resize(image_RGB, image_RGB, Size(400, 300));
	Mat image_hsv;
	cvtColor(image_RGB, image_hsv, COLOR_BGR2HSV);
	namedWindow("image_hsv", WINDOW_AUTOSIZE);
	moveWindow("image_hsv", 400, 200);
	imshow("image_hsv", image_hsv);
	Mat mask;
	//将规定区间内的值置为255;必须使用Scalar()来赋值
	inRange(image_hsv, Scalar(35, 43, 46), Scalar(99, 255, 255), mask);
	//mask为二值图像,CV_8UC
	namedWindow("mask", WINDOW_AUTOSIZE);
	moveWindow("mask", 400, 200);
	imshow("mask", mask);
	Mat output;
	bitwise_and(image_RGB, image_RGB, output, mask);
	namedWindow("output", WINDOW_AUTOSIZE);
	moveWindow("output", 400, 200);
	imshow("output", output);

首先读取一张RGB图像并将其转化为HSV图像,然后通过inRange(image_hsv, Scalar(35, 43, 46), Scalar(99, 255, 255), mask)这个函数来提取色彩空间。该函数的第一个参数为输入图像;第二个参数为我们想要提取的色彩范围的低值;第三个参数为我们想要提取的色彩范围的高值;第四个参数为输出的Mat对象mask,mask是一张和输入图像尺寸相同的二值图像,输入图像中在规定的色彩范围内的区域,即为mask中值为255的区域,输入图像中不在规定的色彩范围内的区域,即为mask中值为0的区域。
随后使用bitwise_and(image_RGB, image_RGB, output, mask);将两张原图像做与(and)操作,并以上面得到的mask作为掩膜,就可以将原图像中符合规定色彩范围的区域提取出来。效果如下:
在这里插入图片描述
这里是提取了图像的背景,如果用原图像减去这张输出图像,就可以将图像的前景“人”给抠了出来。

总结:也就是说,对于一幅HSV图像,我们可以通过这种方法来提取图像中我们想要的颜色。如果图像的前景和背景是不同颜色的,也可以利用这种方法来分离前景和背景,但这只适用于色彩比较单一且色彩差异较大的图像。而且这种方法的前提是我们事先知道所要提取颜色的色调范围,下图给出了部分颜色的色调取值范围,可以通过该图来设置inRange()函数的低值和高值。
在这里插入图片描述

  1. 像素统计
    图像像素统计方法主要有:最大、最小像素值及其位置坐标的获取,图像像素的均值和方差,像素归一化。
    (1)最大、最小像素值及其位置坐标的获取,主要代码如下:
	double minVal, maxVal;
	Point minLoc, maxLoc;
	Mat image_gray;
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	minMaxLoc(image_gray, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
	cout << minVal << "," << maxVal << endl;
	cout << minLoc.x << "," << minLoc.y << endl;
	cout << maxLoc.x << "," << maxLoc.y << endl;

其中,主要使用minMaxLoc(image_gray, &minVal, &maxVal, &minLoc, &maxLoc, Mat());这个函数来获取最大、最小像素值及其位置坐标。
其第一个参数是输入图像,可以为单通道图也可以是三通道图,如果是单通道图则输出的值只有一个,如果是三通道图则输出一个数组,其中有三个元素,当然输出的变量是需要根据输入的不同来提前定义的;
第二、三个参数分别为最小值和最大值,这里输入的是一个变量的引用;
第四、五个参数为最小、最大值的位置坐标,输入的同样是个引用;
最后一个参数是掩膜,如果没有的话可以不填,也可以填上Mat()。
(2)计算像素均值和方差,主要代码如下:

	Mat mean, stddev;
	meanStdDev(image, mean, stddev);			//对于三通道图,输出的均值和方差为[3, 1]的Mat对象,三行分别为三通道
	cout << mean.at<double>(0, 0) << endl;
	cout << mean.at<double>(1, 0) << endl;
	cout << mean.at<double>(2, 0) << endl;
	cout << stddev.at<double>(0, 0) << endl;
	cout << stddev.at<double>(1, 0) << endl;
	cout << stddev.at<double>(2, 0) << endl;

使用meanStdDev(image, mean, stddev); 这个函数来计算均值和方差。
第一个参数是输入图像,同样可以是单通道或三通道图像。对于三通道图,输出的均值和方差为[3, 1]的Mat对象,三行分别为三通道;
第二个参数是计算得到的均值,对于三通道图,输出的均值为[3, 1]的Mat对象,三行分别为三通道;
第三个参数是计算得到的方差,对于三通道图,输出的方差为[3, 1]的Mat对象,三行分别为三通道。
最后输出时,访问Mat对象某一点的值使用.at<_type>(row,col)来实现,这里的均值和方差都是浮点型并且以double类型输出,如果不需要太高精度也可以用float类型输出。

(3)像素归一化,主要代码如下:

	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	gray.convertTo(gray, CV_32F);			//将uchar类型转换为32位浮点型
	Mat gray_norm;
	normalize(gray, gray_norm, 0, 1.0, NORM_MINMAX);			
	Mat dst;
	dst = gray_norm * 255;			//将灰度值恢复到[0, 255]
	dst.convertTo(dst, CV_8UC1);			//浮点型转换为uchar类型后才可以进行显示

注意:对像素值计算时,需要先转换为浮点型,避免数据计算出错,最后显示前要再转换为uchar类型,因为只有uchar类型的数据才能正常显示。使用gray.convertTo(gray, CV_32F);这个函数来将gray转换为CV_32F类型(32位浮点型),输出仍然是gray。

使用normalize(gray, gray_norm, 0, 1.0, NORM_MINMAX);来对像素进行归一化。
第一个参数为输入图像;
第二个参数为输出的经过归一化的图像;
第三、四个参数alpha和beta分别为归一化的低值和高值;
第五个参数为归一化类型,主要有以下四种类型:
(a)在 NORM_MINMAX 模式下,alpha表示归一化后的最小值,beta表示归一化后的最大值。
(b)在NORM_L1、NORM_L2、NORM_INF 模式下,alpha != 0,beta不使用。

一般使用NORM_MINMAX来进行归一化。

最后显示图像前,需要将归一化图像乘以255,以将[ 0 , 1 ] 的灰度值范围变成 [ 0, 255 ] ,再做一次类型转化,将浮点型数值转为uchar类型,才能正常显示。

			本次笔记整理到此,下次有空继续~~~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢

发布了36 篇原创文章 · 获赞 43 · 访问量 1821

猜你喜欢

转载自blog.csdn.net/weixin_45224869/article/details/104540482
今日推荐