opencv学习四:色彩空间转换

一、常见的色彩空间

在这里插入图片描述RGB颜色空间
RGB(red,green,blue)颜色空间最常用的用途就是显示器系统,彩色阴极射线管,彩色光栅图形的显示器 都使用R、G、B数值来驱动R、G、B 电子枪发射电子,并分别激发荧光屏上的R、G、B三种颜色的荧光粉 发出不同亮度的光线,并通过相加混合产生各种颜色;扫描仪也是通过吸收原稿经反射或透射而发送来 的光线中的R、G、B成分,并用它来表示原稿的颜色。RGB色彩空间称为与设备相关的色彩空间,因为不同 的扫描仪扫描同一幅图像,会得到不同色彩的图像数据;不同型号的显示器显示同一幅图像,也会有不同 的色彩显示结果。显示器和扫描仪使用的RGB空间与CIE 1931 RGB真实三原色表色系统空间是不同的,后者 是与设备无关的颜色空间。btw:Photoshop的色彩选取器(Color Picker)。可以显示HSB、RGB、LAB和CMYK 色彩空间的每一种颜色的色彩值。
HSV颜色空间
HSV(hue,saturation,value)颜色空间的模型对应于圆柱坐标系中的一个圆锥形子集,圆锥的顶面对应于V=1. 它包含RGB模型中的R=1,G=1,B=1 三个面,所代表的颜色较亮。色彩H由绕V轴的旋转角给定。红色对应于 角度0° ,绿色对应于角度120°,蓝色对应于角度240°。在HSV颜色模型中,每一种颜色和它的补色相差180° 。 饱和度S取值从0到1,所以圆锥顶面的半径为1。HSV颜色模型所代表的颜色域是CIE色度图的一个子集,这个 模型中饱和度为百分之百的颜色,其纯度一般小于百分之百。在圆锥的顶点(即原点)处,V=0,H和S无定义, 代表黑色。圆锥的顶面中心处S=0,V=1,H无定义,代表白色。从该点到原点代表亮度渐暗的灰色,即具有不同 灰度的灰色。对于这些点,S=0,H的值无定义。可以说,HSV模型中的V轴对应于RGB颜色空间中的主对角线。 在圆锥顶面的圆周上的颜色,V=1,S=1,这种颜色是纯色。HSV模型对应于画家配色的方法。画家用改变色浓和 色深的方法从某种纯色获得不同色调的颜色,在一种纯色中加入白色以改变色浓,加入黑色以改变色深,同时 加入不同比例的白色,黑色即可获得各种不同的色调。
HSI颜色空间
HSI色彩空间是从人的视觉系统出发,用色调(Hue)、色饱和度(Saturation或Chroma)和亮度 (Intensity或Brightness)来描述色彩。HSI色彩空间可以用一个圆锥空间模型来描述。用这种 描述HIS色彩空间的圆锥模型相当复杂,但确能把色调、亮度和色饱和度的变化情形表现得很清楚。 通常把色调和饱和度通称为色度,用来表示颜色的类别与深浅程度。由于人的视觉对亮度的敏感 程度远强于对颜色浓淡的敏感程度,为了便于色彩处理和识别,人的视觉系统经常采用HSI色彩空间, 它比RGB色彩空间更符合人的视觉特性。在图像处理和计算机视觉中大量算法都可在HSI色彩空间中 方便地使用,它们可以分开处理而且是相互独立的。因此,在HSI色彩空间可以大大简化图像分析 和处理的工作量。HSI色彩空间和RGB色彩空间只是同一物理量的不同表示法,因而它们之间存在着 转换关系。

HSI 色彩模型是从人的视觉系统出发,用 H 代表色相 (Hue)、S 代表饱和度 (Saturation) 和 I 代表亮度 (Intensity) 来描述色彩。饱和度与颜色的白光光量刚好成反比,它可以说是一个颜色鲜明与否的指标。因此如果我们在显示器上使用 HIS 模型来处理图像,将能得到较为逼真的效果。
色相 (Hue):指物体传导或反射的波长。更常见的是以颜色如红色,橘色或绿色来辨识,取 0 到 360 度的数值来衡量。
饱和度 (Saturation):又称色度,是指色彩的强度或纯度。饱和度代表灰色与色调的比例,并以 0% (灰色) 到 100% (完全饱和) 来衡量。
亮度 (Intensity):是指颜色的相对明暗度,通常以 0% (黑色) 到 100% (白色) 的百分比来衡量。
YCrCb颜色空间
YCrCb即YUV,主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。   采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。   YUV与RGB相互转换的公式如下(RGB取值范围均为0-255)︰   Y = 0.299R + 0.587G + 0.114B   U = -0.147R - 0.289G + 0.436B   V = 0.615R - 0.515G - 0.100B   R = Y + 1.14V   G = Y - 0.39U - 0.58V   B = Y + 2.03U   在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。   在人脸检测中也常常用到YCrCb空间,因为一般的图像都是基于RGB空间的,在RGB空间里人脸的肤色受亮度影响相当大,所以肤色点很难从非肤色点中分离出来,也就是说在此空间经过处理后,肤色点是离散的点,中间嵌有很多非肤色,这为肤色区域标定(人脸标定、眼睛等)带来了难题。如果把RGB转为YCrCb空间的话,可以忽略Y(亮度)的影响,因为该空间受亮度影响很小,肤色会产生很好的类聚。这样就把三维的空间将为二维的CrCb,肤色点会形成一定得形状,如:人脸的话会看到一个人脸的区域,手臂的话会看到一条手臂的形态,对处理模式识别很有好处,根据经验某点的CrCb值满足:133≤Cr≤173,77≤Cb≤127 那么该点被认为是肤色点,其他的就为非肤色点。
YCrCb颜色空间在做肤色检测上有很好的效果,比HSV颜色空间要好一些
查阅一些网上的资料得知,正常黄种人的Cr分量大约在140 ~ 175之间,Cb分量大约在100 ~ 120之间。
参考博客:YCrCb颜色空间与肤色检测

YCbCr与YUV的区别
yuv色彩模型来源于rgb模型,该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。

YCbCr模型来源于yuv模型,应用于数字视频,ITU-R BT.601 recommendation

通过上面的比较可以确定,我们在h.264,mpeg等编码标准中用的yuv其实是YcbCr,大家不要被名称搞混淆了。
为了使用人的视角特性以降低数据量,通常把RGB空间表示的彩色图像变换到其他彩色空间。目前采用的彩色空间变换有三种:YIQ, YUV和YCrCb。每一种彩色空间都产生一种亮度分量信号和两种色度分量信号,而每一种变换使用的参数都是为了适应某种类型的显示设备。其中,YIQ适用于NTSC彩色电视制式,YUV适用于PAL和SECAM彩色电视制式,而YCrCb适用于计算机用的显示器。

YUV不是那几个英文单词的组合词,而是符号,Y表示亮度,UV用来表示色差,U、V是构成彩色的两个分量。

YUV 的优点:
1 、 YUV 表示法的重要性是它的亮度信号 (Y) 和色度信号 (U 、 V) 是 相互独立的 。
2 、 YUV 表示法的另一个优点是可以利用人眼的特性来降低数字彩 色图像所需要的存储容量。

YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。
YCbCr 则是在世界数字组织视频标准研制过程中作为ITU - R BT1601 建议的一部分, 其实是YUV经过缩放和偏移的翻版。其中Y与YUV 中的Y含义一致, Cb , Cr 同样都指色彩, 只是在表示方法上不同而已。在YUV 家族中, YCbCr 是在计算机系统中应用最多的成员, 其应用领域很广泛,JPEG、MPEG均采用此格式。一般人们所讲的YUV大多是指YCbCr。YCbCr 有许多取样格式, 如4∶4∶4 , 4∶2∶2 , 4∶1∶1 和4∶2∶0。

二、调用转换函数实现图像色彩空间转换

代码如下:

import cv2 as cv  #导入cv模块

#色彩空间的转换
def color_space_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)#RGB转换为gray
    cv.imshow("gray", gray)
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)#RGB转换为hsv
    cv.imshow("hsv", hsv)
    yuv = cv.cvtColor(image, cv.COLOR_BGR2YUV)#RGB转换为yuv
    cv.imshow("yuv", yuv)
    ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)#RGB转换为ycrcb
    cv.imshow("ycrcb", ycrcb)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
#blue green red
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)  #创建一个GUI
cv.imshow("input image", src) #对窗口图片进行展示
color_space_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()  #释放所有的内存

运行截图:
在这里插入图片描述HSV色彩空间说明:
H:0-180 S: 0-255 V: 0-255
可以通过下表对应颜色的数值过滤其他颜色
HSV颜色对应RGB的分量范围
在这里插入图片描述

三、色彩空间转换,利用inRange函数过滤视频中的颜色,实现跟踪某一颜色

代码如下:

import cv2 as cv  #导入cv模块
import numpy as np #np科学计数的包,通过numpy对数据进行处理

def extrace_object_demo():
    capture = cv.VideoCapture("C:/Users/lenovo/Desktop/opencv/daima/banknum/test.mp4") #导入视频
    while(True):
        ret, frame = capture.read()
        if ret == False:
            break;
        hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) #转换色彩空间为hsv
        #设置绿色的范围,跟踪视频中的绿色
        lower_hsv = np.array([37, 43, 46])#设置过滤的颜色的低值
        upper_hsv = np.array([77, 255, 255])#设置过滤的颜色的高值
        mask = cv.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv)#调节图像颜色信息(H)、饱和度(S)、亮度(V)区间,选择绿色区域
        cv.imshow("video", frame)
        cv.imshow("mask", mask)
        c = cv.waitKey(40)
        if c == 27:
            break

extrace_object_demo()
cv.waitKey(0)
cv.destroyAllWindows()

运行截图:
在这里插入图片描述inRange函数很简单,参数有三个
第一个参数:hsv指的是原图
第二个参数:lower_red指的是图像中低于这个lower_red的值,图像值变为0,即为黑色
第三个参数:upper_red指的是图像中高于这个upper_red的值,图像值变为0
而在lower_red~upper_red之间的值变成255,即为白色

四、通道分离、合并,修改某一通道

涉及函数:
split() 将彩色图像分割成3个通道
merge()通道合并
代码如下:

import cv2 as cv
import numpy as np
 
 
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
#blue green red
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)  #创建一个GUI
cv.imshow("input image", src) #对窗口图片进行展示
 
#通道分离,输出三个单通道图片
b, g, r = cv.split(src)#将彩色图像分割成3个通道
cv.imshow("blue", b)
cv.imshow("green", g)
cv.imshow("red", r)
 
#通道合并
src = cv.merge([b, g, r]) #将三个通道进行合并
cv.imshow("changed image", src)
 
#修改某个通道的值
src[:, :, 2] = 0 #将红色通道改为0
cv.imshow("single", src)
 
cv.waitKey(0)
cv.destroyAllWindows()

运行截图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44145452/article/details/112424288