参考教程:
- python+opencv3.3视频教学 基础入门-bilibili
- 颜色空间 - 911的专栏
- 几种颜色模型介绍 - 简书
- 从 RGB 到 HSV 的转换详细介绍 - hanshanbuleng的博客
一、定义
色彩通常用三个相对独立的属性来描述,三个独立变量综合作用,自然就构成一个空间坐标,这就是色彩空间(色彩模型)。
二、常见色彩空间
色彩可以由不同的角度,用三个一组的不同属性加以描述,就产生了不同的色彩空间。
- 最常见的几种色彩空间有:
-
RGB 用于扫描仪和显示设备 、计算机系统
-
CMYK 用于打印机、印刷出版业
-
YUV/YIQ 用于视频和电视
-
HIS/HSB/HSV/HSL
-
CIE 颜色空间,包括:CIE XYZ,CIE Lab,CIE YUV等颜色空间
1.RGB
一个能发出光波的物体称为有源物体,它的颜色由该物体发出的光波决定,使用RGB相加混合模型(additive color)。
国际照明委员会(CIE)规定以700nm(红)、546.1nm (绿)、435.8nm (蓝)三个色光为三基色。又称为物理三基色。自然界的所有颜色都可以通过选用这三基色按不同比例混合而成。
计算机彩色显示器的输入需要RGB三个彩色分量,通过三个分量的不同比例,在显示屏幕上合成所需要的任意颜色。RGB颜色空间的三个分量又称为三个通道,R、G、B分别反映了颜色在某个通道上的亮度值。在RGB彩色空间,任意彩色光F的配色方程可表达为:
F = r[R](红色百分比) +g[G](绿色百分比) + b[B](蓝色百分比)
RGB颜色模型是三维直角坐标颜色系统中的一个正方体。
如下图
在正方体的主对角线上,各原色的量相等,产生由暗到亮的白色,即灰度。(0,0,0)为黑,(255,255,255)为白,正方体的其他6个角点分别为红、黄、绿、青、蓝和品红。
2.HSV
HSV是一种将RGB色彩空间中的点在倒圆锥体中的表示方法。
-
色调H
用角度度量,取值范围为0°~360°(python中取值0~180,可能为了适应uint8),从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°; -
饱和度S
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。 -
明度V
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
2.YUV
YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法。在现代彩色电视系统中,通常采用三管彩色摄像机或彩色CCD摄影机进行取像,然后把取得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端将亮度和两个色差总共三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V信号分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
在YUV颜色模型中:
“Y”表示明亮度(Luminance或Luma),也就是灰阶值;
“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。
而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。
而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。
YUV颜色模型解决了彩色图像和黑白图像的兼容问题,如果只有Y信号而没有U何V信号,那么一幅彩色图像就可以被转换为黑白图像。
- YUV颜色模型可以和RGB颜色模型相互转换。公式如下:
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
三、色彩空间转换
1.色彩空间转换API
常见的转换:
- HSV和RGB
- YUV和RGB
import cv2 as cv
def color_space_demo(image):
"""
色彩空间的转换
- - - -
image - 原图像名
"""
#转化为灰度图像
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imwrite("gray.png",gray)
#转化为HSV图像
hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV)
cv.imwrite("hsv.png",hsv)
#转化为YUV图像
yuv = cv.cvtColor(image,cv.COLOR_BGR2YUV)
cv.imwrite("yuv.png",yuv)
#转化为YCrCb图像
ycrcb = cv.cvtColor(image,cv.COLOR_BGR2YCrCb)
cv.imwrite("ycrcb.png",ycrcb)
if __name__ == "__main__":
src = cv.imread('cat.jpg')
color_space_demo(src)
结果:
2.inRange()函数
通过inRange()函数实现对视频中绿色部分的过滤
RGB到HSV的数值转换参考下表:
import cv2 as cv
import numpy as np
def extrace_object_demo():
"""
通过inRange()函数实现对视频中绿色部分的过滤
"""
capture = cv.VideoCapture('MV.mp4')
while(True):
ret, frame = capture.read()
if ret == False:
break
# 转化为HSV
hsv = cv.cvtColor(frame,cv.COLOR_BGR2HSV)
# 设置绿色数值过滤
lower_hsv = np.array([37,43,46])
upper_hsv = np.array([77,255,255])
mask = cv.inRange(hsv,lowerb=lower_hsv,upperb=upper_hsv)
cv.imshow("video",frame)
cv.imshow("mask",mask)
c = cv.waitKey(40)
if c == 27:
break
if __name__ == "__main__":
extrace_object_demo()
结果:
3.通道的分离与合并
- 使用split()函数实现通道的分离
import cv2 as cv
if __name__ == "__main__":
src = cv.imread('cat.jpg')
# 通道的分离
b,g,r = cv.split(src)
# 分别写入不同的图像
cv.imwrite("blue.png",b)
cv.imwrite("green.png",g)
cv.imwrite("red.png",r)
结果:
- 单独修改某一通道
import cv2 as cv
if __name__ == "__main__":
src = cv.imread('cat.jpg')
src[:, :, 2] = 0
cv.imwrite("changecolor.png",src)
结果:
- 使用merge()函数实现通道的合并
import cv2 as cv
if __name__ == "__main__":
src = cv.imread('cat.jpg')
b,g,r = cv.split(src)
# 改变第2通道
src[:, :, 2] = 0
cv.imwrite("before.png",src)
# 合并原通道恢复图像
src = cv.merge([b,g,r])
cv.imwrite("after.png",src)
结果:
来源:CSDN
作者:nanashi_F
链接:https://blog.csdn.net/nanashi_F/article/details/103663583