【3】OpenCV的色彩空间
一、RGB和BGR
最常见的色彩空间就是RGB,人眼也是基于RGB的色彩空间去分辨颜色的。
OpenCV默认使用的是BGR。
BGR和RGB色彩空间的区别在于图片在色彩通道上的排列顺序不同。
显示图片的时候需要注意适配图片的色彩空间和显示环境的色彩空间。比如传入的图片是BGR色彩空间,现实环境是RGB空间,就会出现颜色混乱的情况。
二、HSV,HSL和YUV
(1)HSV(也叫HSB)
- OpenCV用的最多的色彩空间是HSV。
- Hue:色相,即色彩。如红色、蓝色。用角度度量,取值范围为
0°~360°
,从红色开始按逆时针方向计算。红色为0°,绿色为120°,蓝色为240°。 - Saturation:饱和度,表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例越大,颜色接近光谱色的程度就越高,颜色的饱和度也就越高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为
0%~100%
,值越大,颜色越饱和。 - Value(Brightness):明度。明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
为什么要使用HSV?
方便OpenCV做图像处理。比如根据Hue的值就可以判断背景颜色。
(2)HSL
HSL和HSV差不多。
- Hue:色相。
- Saturation:饱和度。
- Lightness:亮度。
HSV和HSL的区别如下。
HSV和HSL在字面意思上是一样的:
- H指的是色相(Hue),就是颜色名称,例如红色、蓝色;
- S指的是饱和度(Saturation),即颜色的纯度;
- L(Lightness)和B(Brightness)是明度,即颜色的明亮程度。
在原理和表现上,HSL和HSV中的H(色相)完全一致,但二者的S(饱和度)不一样,L和V(明度)也不一样。
- HSV中的S控制纯色中混入白色的量,值越大,白色越少,颜色越纯;
- HSV中的V控制纯色中混入黑色的量,值越大,黑色越少,明度越高;
- HSL中的S和黑白没有关系,饱和度不控制颜色中混入黑白的多少;
- HSL中的L控制纯色中混入的黑白两种颜色。
(3)YUV
YUV,是一种颜色编码方法。常使用在各个视频处理组件中。YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽。
意思就是,对于实际的图片来说,两个像素点的RGB只要有一点不一样,那就是不一样的两个颜色。但是,如果仅仅是因为RGB有细微的差别就算作两个不同颜色的话,对人类的肉眼来说其实是没意义的,人眼也分辨不出来,所以对于这种情况就可以把它压缩一下,适当降低一下精度,也不影响人眼观看时的图片效果。
“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
YUV的发明是由于彩色电视与黑白电视的过渡时期。
YUV最大的优点在于只需占用极少的带宽。
- 4:4:4表示完全取样;
- 4:2:2表示2:1的水平取样,垂直完全采样;
- 4:2:0表示2:1的水平取样,垂直2:1采样;
- 4:1:1表示4:1的水平取样,垂直完全采样。
三、色彩空间的转换
cvtColor(img, colorspace)
:颜色转换的关键API。
import cv2
def callback(value):
pass
cv2.namedWindow('color', cv2.WINDOW_NORMAL)
cv2.resizeWindow('color', 640, 480)
# 读取照片,OpenCV读进来的图片默认是BGR的色彩空间
img = cv2.imread('1.png')
# 定义颜色空间转化列表
colorspaces = [
# 记不住的话,有技巧
# 所有颜色空间的转化都是COLOR开头
# 所以输入cv2.COLOR 然后按tab键自动补全即可
# 这里为什么都是BGR转其他的,因为我们读进来的照片都是BGR
cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA,
cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV,
cv2.COLOR_BGR2YUV
]
# 设置trackbar
cv2.createTrackbar('trackbar', 'color', 0, 4, callback)
while True:
# 获取trackbar的值
index = cv2.getTrackbarPos('trackbar', 'color')
# 进行颜色空间转换
cvt_img = cv2.cvtColor(img, colorspaces[index])
cv2.imshow('color', cvt_img)
key = cv2.waitKey(10)
if key == ord('q'):
break
cv2.destroyAllWindows()