点击上方“”,选择加"
重磅干货,第一时间送达 引言
重写图像色彩空间的相关知识,希望能给大家更多的背景和理解,不说别的,看完肯定会提高知识。
图像处理最基本的知识点之一是图像颜色和颜色模型,表示计算机的图像
例如,只有一些零一的二进制值,但人眼看到的是一些可见光,人眼只对红色三种可见光敏感(red)、绿色(green)、蓝色(blue)。这是最基本的RGB三种颜色的波长范围如下:
Blue: 450–495 nm Green: 495–570 nm Yellow: 570–590 nm
1931年,国际照明协会发布了一个色彩模型/色彩空间,针对人下:
因此,相应颜色模型的颜色空间出现了CIE XYZ模型表示色度和亮度,图如下:
从上面看不到Z,其实Z是指颜色的亮度或深度,所以CIE XYZ这张颜色模型的图被称为CIE 色度图。CIE XYZ颜色模型表示范围较大,因此微软和惠普后来提出了其子集的颜色模型sRGB其中,S是英文单词标准的首字母,sRGB色彩空间的表现如下:
上述黑色三角形区域称为sRGB色彩空间广泛应用于个人电脑显示器、打印机和数码相机,占据了大量的市场份额。20世纪90年代Adobe公司提出了新的建议RGB色彩空间模型Adobe RGB色彩空间,它比sRGB色彩空间具有较大的值范围,因此色彩更加细腻丰富,其色彩空间图如下:
从图中可以看出Adobe RGB色彩空间是比较sRGB色彩空间很大,但也有缺陷,即不同颜色空间产生的颜色图像在不同的设备上显示或浏览。为了解决这个问题,有必要在不同的颜色空间之间建立一个转换模型,以实现不同颜色空间模型的转换。RGB色彩空间被大家玩坏了,现在常用RGB色彩空间如下:
值得注意的部分是sRGB跟CMYK之间的相互转换会导致明显的颜色差异,因为CMYK另一部分颜色空间不在sRGB因此,在这种情况下,需要内部RGB非线性变换颜色空间,获得颜色补偿。原因是大多数商业打印机都是基于四色的(Cyan, Yellow, Magenta and Black),不能打印一些sRGB范围内的颜色必须进行非线性变换和补偿。其中最常见的个Gamma校正。
RGB色彩空间丰富,但也有缺点。最大的缺点是无法直观区分图像的颜色、亮度和饱和度。因此,我们需要一些更直观的图像色彩空间。HSV色彩空间,直观易懂,在图像处理中非常有用。
RGB立方图的色彩空间无法很好地区分色彩与亮度的关系。单独调整颜色或亮度不太方便。HSV色彩空间是一个很好的选择,它对色彩和亮度有很好的区别,HSV色彩空间图示如下:
H(Hue) 表示颜色通道,不同的值表示不同的颜色范围
S表示饱和度通道,表示颜色
V代表亮度通道,代表图像亮度水平
在H、S、V通道上对图像亮度跟颜色或者饱和度的调整就非常方便了,另外对一些特定的颜色值进行分离也比较方便了。
YCrCb作为当时数字分量视频的标准,开发了色彩空间YUV颜色空间有一定的相似性,其三个通道的值范围分别定义为:
Y通道:16~235
Cr通道:16~240
Cb通道:16~240
需要特别注意的是,RGB到YCrCb当颜色空间转换时,不同的颜色空间YCrCb色彩空间标准会有所不同,以下标明电视和高清电视YCrCb颜色差异:
显然,它们的转换公式会有所不同,所以看到不同的转换公式就不必大惊小怪了!
LAB色彩空间又称CIE Lab / LAB,图表如下:
其中:
L通道表示亮度值
A通道表示红色/绿色
B通道表示蓝色/黄色
在LAB色彩空间,L表示亮度分量,AB表示颜色通道,所以有时候LAB色彩空间处理图像也是必然的RGB色彩空间好用,会有意想不到的好结果。
OpenCV支持色彩空间转换的函数主要有两个:
void cv::cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 )
参数解释如下
src 表示输入图像
dst 表示输出图像
code 表示空间转换代码,支持各种常见的颜色空间转换
从色彩空间中提取不同空间中提取:
void cv::inRange( InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst )
参数说明如下:
src是输入图像
lowerb是取值范围的最小值
upperb是取值范围的最大值
dst是输出的mask图像,二值
例如,从绿色背景对象中提取前景对象,先看效果:
1#include<opencv2/opencv.hpp> 2#include<iostream> 3 4usingnamespacecv; 5usingnamespacestd; 6 7intmain(intargc,constchar*argv[]) 8{ 9Matsrc=imread("D:/vcprojects/images/cat.jpg"); 10if(src.empty()){ 11printf("couldnotloadimage...\n"); 12return-1; 13} 14namedWindow("input",WINDOW_AUTOSIZE); 15imshow("input",src;
16
17 // RGB to HSV
18 Mat hsv;
19 cvtColor(src, hsv, COLOR_BGR2HSV);
20 imshow("hsv", hsv);
21
22 // RGB to YUV
23 Mat yuv;
24 cvtColor(src, yuv, COLOR_BGR2YUV);
25 imshow("yuv", yuv);
26
27 // RGB to YUV
28 Mat ycrcb;
29 cvtColor(src, ycrcb, COLOR_BGR2YCrCb);
30 imshow("ycrcb", ycrcb);
31
32 Mat src2 = imread("D:/javaopencv/tinygreen.png");
33 imshow("src2", src2);
34 cvtColor(src2, hsv, COLOR_BGR2HSV);
35 Mat mask;
36 inRange(hsv, Scalar(35, 43, 46), Scalar(99, 255, 255), mask);
37 imshow("mask", mask);
38
39 waitKey(0);
40 return 0;
41}
在「
在「
在「
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。