RGB颜色空间

颜色空间使用R 、G 、B ,3 个颜色通道可以表示任何的颜色、灰度级。






考虑到效率,RGB 颜色空间表示中颜色是用24 位来表示的,R 、G 、B 每一个通道占8 位,即每一个通道的值的取值范围是[0,255] ,例如:白色在RGB 空间的表示是:R 通道的值是255 ,B 通道的值是255 ,G 通道的值也是255 。我们可以计算一下RGB 颜色空间能表示的颜色种类有255*255*255=16581375 种。






这种颜色表示的方法已经使用了很多年(例如电脑屏幕),所以在计算软件中,这个是标准的颜色格式。







然而在计算机视觉中,RGB并不是那么的稳定,因为这个颜色表示容易受到强光,弱光,阴影等因素的影响。相比之下,HSV空间面对这些光照的变化更稳定一些,能很好的反应颜色的本质。

 



HSV颜色空间

、S 、V 这3 个字母分别代表Hue---Saturation---Value ,Hue 表示的是颜色也称为色度,由于颜色很难被分离,Hue 通常使用一个带有角度的圆形表示(存储时,是0.0 到1.0 的浮点数),如图所示。在圆上的不同角度,表示不同的颜色。


HSV空间的示意图:

 


由于是圆形的,所以也意味着1.0 和0.0 是表示同一种颜色。



通道表示的是色度,即表示是什么颜色。在圆上的不同角度,表示不同的颜色。Hue 取值0.0 时表示的是红色,Hue 在120 度时是表示绿色,在240 度时是表示蓝色。Hue 的取值是用其在角度除以360.



例如在120 度时,Hue=120.0/36.0=0.3333 。






Saturation 表示的是灰度,如图 2 所示 Saturation 在圆心处的取值是 0 ,表示颜色很淡,沿着圆的半径方向, Saturation 的值不断增大,表示颜色越来越浓。






通道表示的是颜色的亮度,如图2 所示,在圆锥的低端Value 表示的  是黑色,在顶端是白色。






Opencv 中的 HSV 格式



在计算机视觉领域,Opencv 是一个非常重要的开源工具,它能够在windows ,linux ,mac ,iPhone 等多种平台上运行。






在Opencv 中,主要的颜色格式是RGB 颜色,(实际上是BGRX 格式,X 是保留位,通常,为简单起见,就称为RGB 颜色)。也包含了很多其他的颜色格式,例如HSV ,YUV ,LAB ,XYZ 等。但是,亲们,在Opencv 中HSV 颜色格式,也许跟你想象的有点不一样哦。






中RGB 转换到HSV 时,对Hue 通道的存储是用一个字节(8 位)来表示,其取值是0 到179 。这就意味着,如果你用Opencv 的cvCvtColor 函数进行颜色格式的转换,会损失颜色分辨率,因为实际上Opencv 只用了7 位来存储Hue 通道的值( 取值范围是0 到179) 。由于这个原因,你使用的其他软件或者库,如果是基于HSV 颜色值来进行图像处理的,那么,你就会碰到一些问题,因为,其他的软件或者库大多是用[0,255] 来表示Hue 通道。






例如:你正在写一个基于HSV 颜色空间的皮肤检测程序,这是你需要找一个HSV 颜色空间的阈值,如果你使用 AdobePhotoshop 等工具来读取肤色颜色,来决定你设定阈值,这时就会有点麻烦,这个 HSV 颜色就会与你 Opencv 程序中的颜色值不一样。






RGB 颜色可以通过多种方式转换到 HSV 颜色,这就会导致同一种 RGB 颜色转到 HSV 颜色时会产生不同的结果。









观察 Opencv 中 HSV 颜色空间



这里有一个互动程序,可以让你进一步的观察 Opencv 中使用 cvCvtColor 函数转换后的 HSV 颜色格式。它是与其他的一些图像编辑软件中的颜色空间不一样。



运行程序后,你在 2D 彩图上随便点击一个地方,就可以看到相应的 HSV 的颜色值,或者也可以通过滑动条来设定。



通过实验,可以发现, OpenCv 中的 H 通道的值是 0 到 178 ,而不是 0 到 255 ,这样就降低了彩色分辨率,在此,提供了颜色转换程序,其 H 通道的值是 0 到 255 的。












RGB 与 HSV 的转换程序




这个RGB与HSV相互转换的程序比Opencv中cvCvtColor的效果要好,因为H通道的取值范围是[0,255],这就提高了精度。这个函数会在内部内存空间,所以,在使用的时候,要记得释放相应的内存空间。



怎么使用这个程序呢?



(1)    正确的使用方法:




1.  IplImage *imHSV;
2.  imHSV = convertRGBtoHSV(imRGB);        // RGB转换到HSV颜色空间
3.  ......
4.  ......
5.  cvReleaseImage(&imHSV);                // 释放空间
6.  cvReleaseImage(&imRGB);                // 释放空间

复制代码




(2)    错误的使用方法:这会导致内存泄露




1.  IplImage *imHSV;
2.  imHSV = cvCreateImage(...);        // 创建HSV存放的空间 (错误的做法,因为在convertRGBtoHSV会给HSV分配空间).

复制代码




YIQ 与 RGB 的转换



这里还提供了 YIQ 转到 RGB , RGB 转换到 YIQ 的程序, YIQ 格式在电视广播等领域中的应用非常的普遍。因为它的转换使用过一个一个线性矩阵相乘实现的。看起来比 HSV 更平滑( HSV 是一个非线性的转换