色彩空间类型转换
- 色彩空间基础
- GRAY色彩空间
- XYZ色彩空间
- YCrCb色彩空间
- HSV色彩空间
- HLS色彩空间
- CIEL\*a\*b*色彩空间
- CIEL\*u\*v*色彩空间
- Bayer色彩空间
- 类型转换函数
- HSV色彩空间
- 概述
- 标记指定颜色
- 通过inRange函数锁定特定值
- 实现艺术效果
- alpha通道
色彩空间基础
GRAY色彩空间
即8位灰度图,具有256个灰度级,像素值范围是[0,255]
RGB色彩空间–>GRAY色彩空间:
- 标准转换:Gray = 0.299·R+0.587·G+0.114·B
- 简化形式:Gray = (R+G+B)/3
GRAY色彩空间–>RGB色彩空间:
- 所有通道的值都相同:R = Gray G = Gray B = Gray
XYZ色彩空间
由CIE定义,相对计算更为容易的色彩空间。也可以与RGB色彩空间相互转换,只需要乘上一个转换矩阵即可。
YCrCb色彩空间
人眼视觉系统对颜色的敏感度要低于对亮度的敏感度。在YCrCb色彩空间中,Y代表光源的亮度,色度信息保存在Cr(红色分量信息)、Cb(蓝色分量信息)中。
RGB–>YCrCb:
Y = 0.299R + 0.587G + 0.114B
Cr = (R - Y)x 0.713 + delta
Cb = (B - Y)x 0.564 + delta
delta = 128(8位图像)|| 32768(16位图像)|| 0.5(单精度图像)
YCrCb–>RGB:
R = Y + 1.403 x (Cr - delta)
B = Y + 1.773 x (Cb - delta)
G = Y - 0.714 x (Cr - delta)- 0.344 x (Cb - delta)
HSV色彩空间
将色彩空间分为三要素:
- 色调 Hue :取值区间[0,360],不同的值代表不同的颜色。
- 饱和度 Saturation :取值区间[0,1],0时只有灰度,具体指所选颜色与该颜色最大纯度值之间的比值。
- 亮度 Value :取值区间[0,1],表示色彩的明亮程度。
色彩转换方式有相应的公式,可自行搜索。实践中,可以考虑cv2.cvtColor()函数。
HLS色彩空间
与HSV类似,
分为三要素:色调 Hue 光亮度 Lightness 饱和度 Saturation
光亮度 Lightness:控制色彩的明暗变化,衡量有多少光线从物体表面反射出来。
CIEL*a*b*色彩空间
均匀色彩空间模型:在色彩空间中,如果人观察到的两种颜色的区别程度,与这两种颜色在该色彩空间中对应的点之间的欧氏距离成正比,则其为均匀色彩空间。
CIEL*a*b*中的分量:
L*:像素亮度,取值范围[0,100],纯黑到纯白
a*:从红色到绿色的范围,取值范围[-127,127]
b*:从黄色到蓝色的范围,取值范围[-127,127]
CIEL*u*v*色彩空间
同为均匀色彩空间模型,适用于显示器显示和根据加色原理进行组合的场合,该模型比较强调对红色的表示,对红色变化比较敏感,对蓝色变化不太敏感。
Bayer色彩空间
广泛应用在CCD和CMOS相机中。能够从单平面R、G、B交错表内获取彩色图像。
类型转换函数
在openCV中,使用cv2.cvtColor()实现色彩空间的变换。
语法格式: dst = cv2.cvtColor(src,code [,dstCn])
其中:
dst = 输出图像
src = 输入图像
code = 色彩空间转换码
dstCn = 目标图像通道数。默认为0,即通道数自动通过输入图像和code得到。
tips:转换过程并不是精准可逆,因为有可能存在值的映射过程。
import cv2
# 读取RGB图像
jimin = cv2.imread("C:\\Users\\NNoisy\\Desktop\\Jimin.jpg")
# 转化为灰度图
gray = cv2.cvtColor(jimin , cv2.COLOR_BGR2GRAY)
# 将上述灰度图重新转化为rgb图
rgb = cv2.cvtColor(gray , cv2.COLOR_GRAY2RGB)
# 打印两个图像的shape属性,主要为了看通道数
print("gray shape",gray.shape)
print("rgb shape",rgb.shape)
# 显示图像
cv2.imshow("jimin",jimin)
cv2.imshow("gray",gray)
cv2.imshow("rgb",rgb)
cv2.waitKey()
cv2.destroyAllWindows()
可以看出来,运行之后,实现了色彩空间的转换,但是从灰度图向RGB图转换之后,图像仍然是灰色的,是因为,在转换的过程中丢失了RGB颜色的比例,所以理论上是不可能恢复到原来的彩色的。可以参考上边关于灰度和RGB相互转换的公式。
HSV色彩空间
概述
相对于RGB色彩空间,HSV更加直观,我们可以更方便的使用色调、饱和度、亮度来感知颜色。
色调:取值范围是[0,360],但是八位图像的灰度值取值范围是[0,255],所以在转换的过程中,需要将色调的角度值映射到[0,255]中去,可以直接将角度值除以2,得到[0,180]的取值范围。
饱和度&亮度:同理,[0,1]表示的亮度和饱和度也需要进行值的映射过程,将其映射到[0,255]的范围内。
标记指定颜色
通过inRange函数锁定特定值
函数名:cv2.inRange()
用途:判断图像内像素点的像素值是否在指定范围
语法格式: dst = cv2.inRange(src , lowerb , upperb)
dst = 输出结果 src = 输入图像或数组
lowerb = 范围下界 upperb = 范围上界
输出结果:如果src处于该指定区间内,则dst中对应位置的值为255,否则为0
import cv2
import numpy as np
jimin = cv2.imread("C:\\Users\\NNoisy\\Desktop\\Jimin.jpg")
# 将图像转换为HSV色彩显示
hsv = cv2.cvtColor(jimin,cv2.COLOR_BGR2HSV)
cv2.imshow("jimin",jimin)
# 指定图像的红色区域
minred = np.array([0,50,50])
maxred = np.array([30,255,255])
mask = cv2.inRange(hsv , minred , maxred)
# 通过掩码控制的按位与运算,锁定红色区域
red = cv2.bitwise_and(jimin , jimin , mask=mask)
cv2.imshow("red" , red)
cv2.waitKey()
cv2.destroyAllWindows()
通过掩码的按位与方式,可以实现标记肤色等其他操作。
实现艺术效果
原理:通过改变HSV的三个通道的值,例如,改变亮度等,可以实现图像的一些艺术性的效果
流程如下:
- 打开RGB或者其他格式的彩色文件
- 通过cv2.cvtColor()将其转换为HSV色彩
- 通过cv2.split()分解HSV的三个通道
- 根据需要更改通道值
- 通过cv2.merge()合并HSV三个通道
- 通过cv2.cvtColor()将其转换为RGB色彩
- 通过cv2.imshow()显示图像
import cv2
import numpy as np
jimin = cv2.imread("C:\\Users\\NNoisy\\Desktop\\Jimin.jpg")
# 将图像转换为HSV色彩显示
hsv = cv2.cvtColor(jimin,cv2.COLOR_BGR2HSV)
# 通道分解
h,s,v = cv2.split(hsv)
# 改变颜色饱和度
s[:,:] = 255
# 通道合并
mergehsv = cv2.merge([h,s,v])
# 将图像转换为BGR色彩显示,因为转换后的hsv色彩图像着实看着难受
art = cv2.cvtColor(mergehsv , cv2.COLOR_HSV2BGR)
cv2.imshow("jimin" , jimin)
cv2.imshow("art" , art)
cv2.waitKey()
cv2.destroyAllWindows()
alpha通道
在RGB的基础上,可以增加alpha通道,也即A通道,表示透明度。四个通道的色彩空间被称为RGBA色彩空间,例如:png图像就是4通道图像。
alpha的取值范围可以实[0,1]也可以是[0,255]表示从透明到不透明。
import cv2
import numpy as np
jimin = cv2.imread("C:\\Users\\NNoisy\\Desktop\\Jimin.jpg")
# 将图像转换为RGBA色彩显示
cvtjimin = cv2.cvtColor(jimin , cv2.COLOR_BGR2BGRA)
# 通道拆分
b,g,r,a = cv2.split(cvtjimin)
# 改变alpha的值
a[:,:] = 50
jimin125 = cv2.merge([b,g,r,a])
cv2.imshow("jimin",jimin)
cv2.imshow("jimin125",jimin125)
cv2.waitKey()
cv2.destroyAllWindows()
# 将改变alpha的图像保存文件
cv2.imwrite("cvtjimin125.png",jimin125)
可以看出来,图像在显示的时候虽然alpha通道值不一样,但是显示上无差别,但是如果单独保存文件下来,则会显示出其透明的属性。