OpenCV-Python快速入门(四):色彩空间
前言
- 本文是个人快速入门OpenCV-Python的电子笔记,由于水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入
OpenCV-Python快速入门专栏或我的个人主页查看
前提条件
- 熟悉Python
实验环境
- Python 3.x (面向对象的高级语言)
- OpenCV 4.0(python第三方库)
pip3 install opencv-python
色彩空间
- 色彩空间也称为颜色空间、彩色空间、颜色模型、彩色系统、彩色模型、色彩模型等。
- RGB 图像是一种比较常见的色彩空间类型。
- 比较常见的包括 GRAY 色彩空间(灰度图像)、XYZ 色彩空间、YCrCb 色彩空间、HSV 色彩空间、HLS色彩空间、CIEL*a*b*色彩空间、CIEL*u*v*色彩空间、Bayer 色彩空间、RGBA 色彩空间等。
- 每个色彩空间都有自己擅长的处理问题的领域,因此,为了更方便地处理某个具体问题,就要用到色彩空间类型转换。
GRAY色彩空间
- GRAY(灰度图像)通常指 8 位灰度图,其具有 256 个灰度级,像素值的范围是[0,255]。
- RGB 色彩空间转换为 GRAY 色彩空间的公式: G r a y = 0.299 ⋅ 𝑅 + 0.587 ⋅ 𝐺 + 0.114 ⋅ 𝐵 Gray = 0.299 · 𝑅 + 0.587 · 𝐺 + 0.114 · 𝐵 Gray=0.299⋅R+0.587⋅G+0.114⋅B
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
img_gray=cv2.cvtColor(img1_resize,cv2.COLOR_BGR2GRAY)
gray_img=cv2.cvtColor(img_gray,cv2.COLOR_GRAY2BGR)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2GRA",img_gray)
cv2.imshow("cv2.COLOR_GRAY2BGR",gray_img)
cv2.waitKey()
cv2.destroyAllWindows()
XYZ 色彩空间
- XYZ 色彩空间是由 CIE(International Commission on Illumination)定义的,是一种更便于计算的色彩空间,它可以与 RGB 色彩空间相互转换。
- RGB 色彩空间转换为 XYZ 色彩空间的公式: [ X Y Z ] = [ 0.412453 0.357580 0.180423 0.212671 0.715160 0.072169 0.019334 0.119193 0.950227 ] [ R G B ] \left[ \begin{matrix} X\\ Y \\ Z \end{matrix} \right]=\left[ \begin{matrix} 0.412453 & 0.357580 & 0.180423\\ 0.212671 & 0.715160 & 0.072169\\ 0.019334 & 0.119193 & 0.950227 \end{matrix} \right]\left[ \begin{matrix} R\\ G \\ B \end{matrix} \right] ⎣ ⎡XYZ⎦ ⎤=⎣ ⎡0.4124530.2126710.0193340.3575800.7151600.1191930.1804230.0721690.950227⎦ ⎤⎣ ⎡RGB⎦ ⎤
- XYZ 色彩空间转换为 RGB 色彩空间的公式: [ R G B ] = [ 3.240479 − 1.53715 − 0.498535 − 0.9692561 1.875991 0.041556 0.055648 − 0.204043 1.057311 ] [ X Y Z ] \left[ \begin{matrix} R\\ G \\ B \end{matrix} \right]=\left[ \begin{matrix} 3.240479 & -1.53715 & -0.498535\\ -0.9692561 & 1.875991 & 0.041556\\ 0.055648 & -0.204043 & 1.057311 \end{matrix} \right]\left[ \begin{matrix} X\\ Y \\ Z \end{matrix} \right] ⎣ ⎡RGB⎦ ⎤=⎣ ⎡3.240479−0.96925610.055648−1.537151.875991−0.204043−0.4985350.0415561.057311⎦ ⎤⎣ ⎡XYZ⎦ ⎤
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
XYZ = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2XYZ)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2XYZ",XYZ)
cv2.waitKey()
cv2.destroyAllWindows()
YCrCb色彩空间
- 人眼视觉系统(HVS,Human Visual System)对颜色的敏感度要低于对亮度的敏感度。
- 在传统的 RGB 色彩空间内,RGB 三原色具有相同的重要性,但是忽略了亮度信息。
- 在 YCrCb 色彩空间中,Y 代表光源的亮度,色度信息保存在 Cr 和 Cb 中,其中,Cr 表示红色分量信息,Cb 表示蓝色分量信息。
- 亮度给出了颜色亮或暗的程度信息,该信息可以通过照明中强度成分的加权和来计算。在RGB 光源中,绿色分量的影响最大,蓝色分量的影响最小。
- RGB 色彩空间转换到 YCrCb 色彩空间的公式: 𝑌 = 0.299 ⋅ 𝑅 + 0.587 ⋅ 𝐺 + 0.114 ⋅ 𝐵 𝑌 = 0.299 · 𝑅 + 0.587 · 𝐺 + 0.114 · 𝐵 Y=0.299⋅R+0.587⋅G+0.114⋅B C r = ( 𝑅 − 𝑌 ) × 0.713 + δ Cr = (𝑅 − 𝑌) × 0.713 + \delta Cr=(R−Y)×0.713+δ C b = ( 𝐵 − 𝑌 ) × 0.564 + δ Cb = (𝐵 − 𝑌) × 0.564 + \delta Cb=(B−Y)×0.564+δ其中, δ = { 128 , 8 位图像 32768 , 16 位图像 0.5 ,单精度图像 \delta= \begin{cases} 128, 8 位图像\\ 32768, 16 位图像\\ 0.5, 单精度图像 \end{cases} δ=⎩ ⎨ ⎧128,8位图像32768,16位图像0.5,单精度图像
- YCrCb 色彩空间转换到 RGB 色彩空间的公式:
𝑅 = 𝑌 + 1.403 ⋅ ( C r − δ ) 𝑅 = 𝑌 + 1.403 · (Cr − \delta) R=Y+1.403⋅(Cr−δ) 𝐺 = 𝑌 − 0.714 ⋅ ( C r − δ ) − 0.344 ⋅ ( C b − δ ) 𝐺 = 𝑌 − 0.714 · (Cr − \delta) − 0.344 · (Cb − \delta) G=Y−0.714⋅(Cr−δ)−0.344⋅(Cb−δ) 𝐵 = 𝑌 + 1.773 ⋅ ( C b − δ ) 𝐵 = 𝑌 + 1.773 · (Cb − \delta) B=Y+1.773⋅(Cb−δ)
其中, δ \delta δ同上
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
YCrCb = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2YCrCb)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2YCrCb",YCrCb)
cv2.waitKey()
cv2.destroyAllWindows()
HSV色彩空间
- RGB 是从硬件的角度提出的颜色模型,在与人眼匹配的过程中可能存在一定的差异
- HSV色彩空间是一种面向视觉感知的颜色模型。HSV 色彩空间从心理学和视觉的角度出发,指出人眼的色彩知觉主要包含三要素:色调(Hue,也称为色相)、饱和度(Saturation)、亮度(Value),色调指光的颜色,饱和度是指色彩的深浅程度,亮度指人眼感受到的光的明暗程度。
- 色调:色调与混合光谱中的主要光波长相关,例如“赤橙黄绿青蓝紫”分别表示不同的色调。如果从波长的角度考虑,不同波长的光表现为不同的颜色,实际上它们体现的是色调的差异。
- 饱和度:指相对纯净度,或一种颜色混合白光的数量。纯谱色是全饱和的,像深红色(红加白)和淡紫色(紫加白)这样的彩色是欠饱和的,饱和度与所加白光的数量成反比。
- 亮度:反映的是人眼感受到的光的明暗程度,该指标与物体的反射度有关。对于色彩来讲,如果在其中掺入的白色越多,则其亮度越高;如果在其中掺入的黑色越多,则其亮度越低。
- 在具体实现上,我们将物理空间的颜色分布在圆周上,不同的角度代表不同的颜色。因此,通过调整色调值就能选取不同的颜色,色调的取值区间为[0,360]。色调取不同值时,所代表的颜色如表所示,两个角度之间的角度对应两个颜色之间的过渡色。
色调值(度) 颜色 0 红色 60 黄色 120 绿色 180 青色 240 蓝色 300 品红色
- 饱和度为一比例值,范围是[0, 1],具体为所选颜色的纯度值和该颜色最大纯度值之间的比值。饱和度的值为 0时,只有灰度。亮度表示色彩的明亮程度,取值范围也是[0, 1]。
- 在 HSV 色彩模型中,取色变得更加直观。例如,取值“色调=0,饱和度=1,亮度=1”,则当前色彩为深红色,而且颜色较亮;取值“色调=120,饱和度=0.3,亮度=0.4”,则当前色彩为浅绿色,而且颜色较暗。
- 从 RGB 色彩空间转换到 HSV 色彩空间之前,需要先将 RGB 色彩空间的值转换到[0, 1]之间,然后再进行处理。具体处理方法:
𝑉 = m a x ( 𝑅 , 𝐺 , 𝐵 ) 𝑉 = max (𝑅,𝐺,𝐵) V=max(R,G,B) S = { V − m i n ( 𝑅 , 𝐺 , 𝐵 ) , V ≠ 0 0 , e l s e S= \begin{cases} V-min(𝑅,𝐺,𝐵),\quad V\neq 0\\ 0, \quad else \end{cases} S={V−min(R,G,B),V=00,else H = { 60 ( G − B ) V − m i n ( 𝑅 , 𝐺 , 𝐵 ) , V = R 120 + 60 ( B − R ) V − m i n ( 𝑅 , 𝐺 , 𝐵 ) , V = G 240 + 60 ( R − G ) V − m i n ( 𝑅 , 𝐺 , 𝐵 ) , V = B H= \begin{cases} \frac{60(G-B)}{V-min(𝑅,𝐺,𝐵)},\quad V= R\\ 120+\frac{60(B-R)}{V-min(𝑅,𝐺,𝐵)},\quad V= G\\ 240+\frac{60(R-G)}{V-min(𝑅,𝐺,𝐵)},\quad V= B \end{cases} H=⎩ ⎨ ⎧V−min(R,G,B)60(G−B),V=R120+V−min(R,G,B)60(B−R),V=G240+V−min(R,G,B)60(R−G),V=B- 由于可能存在 H<0 的情况,如果出现这种情况,则需要对 H 进行进一步计算: H = { H + 360 , H < 0 H , e l s e H= \begin{cases} H+360,\quad H<0\\ H,\quad else \end{cases} H={H+360,H<0H,else其中, 𝑆 ∈ [ 0 , 1 ] , 𝑉 ∈ [ 0 , 1 ] , 𝐻 ∈ [ 0 , 360 ] 𝑆 ∈ [0,1],𝑉 ∈ [0,1],𝐻 ∈ [0,360] S∈[0,1],V∈[0,1],H∈[0,360]
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
HSV = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2HSV)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2HSV",HSV)
cv2.waitKey()
cv2.destroyAllWindows()
HLS色彩空间
- HLS 色彩空间包含的三要素是色调 H(Hue)、光亮度/明度 L(Lightness)、饱和度 S(Saturation)。
- 与 HSV 色彩空间类似,只是 HLS 色彩空间用“光亮度/明度 L(lightness)”替换了“亮度(Value)”。
- 色调:表示人眼所能感知的颜色,在 HLS 模型中,所有的颜色分布在一个平面的色调环上,整个色调环为 360 度的圆心角,不同的角度代表不同的颜色。
- 光亮度/明度:用来控制色彩的明暗变化,它的取值范围也是[0, 1]。我们通过光亮度/明度的大小来衡量有多少光线从物体表面反射出来。光亮度/明度对于眼睛感知颜色很重要,因为当一个具有色彩的物体处于光线太强或者光线太暗的地方时,眼睛是无法准确感知物体颜色的。
- 饱和度:使用[0, 1]的值描述相同色调、相同光亮度/明度下的色彩纯度变化。饱和度的值越大,表示颜色的纯度越高,颜色越鲜艳;反之,饱和度的值越小,色彩的纯度越低,颜色越暗沉。通常用该属性表示颜色的深浅,比如深绿色、浅绿色。
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
HLS = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2HLS)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2HLS",HLS)
cv2.waitKey()
cv2.destroyAllWindows()
CIEL*a*b*色彩空间
- CIEL*a*b*色彩空间是均匀色彩空间模型,它是面向视觉感知的颜色模型。从视觉感知均匀的角度来讲,人所感知到的两种颜色的区别程度,应该与这两种颜色在色彩空间中的距离成正比。
- 在某个色彩空间中,如果人所观察到的两种颜色的区别程度,与这两种颜色在该色彩空间中对应的点之间的欧式距离成正比,则称该色彩空间为均匀色彩空间。
- CIEL*a*b*色彩空间中的 L*分量用于表示像素的亮度,取值范围是[0,100],表示从纯黑到纯白;a*分量表示从红色到绿色的范围,取值范围是[-127,127];b*分量表示从黄色到蓝色的范围,取值范围是[-127,127]。
- 在从 RGB 色彩空间转换到 CIEL*a*b*色彩空间之前,需要先将 RGB 色彩空间的值转换到[0, 1]之间,然后再进行处理。
- 由于CIEL*a*b*色彩空间是在CIE的XYZ色彩空间的基础上发展起来的,在具体处理时,需要先将 RGB 转换为 XYZ 色彩空间,再将其转换到 CIEL*a*b*色彩空间。具体实现方法为: [ X Y Z ] = [ 0.412453 0.357580 0.180423 0.212671 0.715160 0.072169 0.019334 0.119193 0.950227 ] [ R G B ] \left[ \begin{matrix} X\\ Y \\ Z \end{matrix} \right]=\left[ \begin{matrix} 0.412453 & 0.357580 & 0.180423\\ 0.212671 & 0.715160 & 0.072169\\ 0.019334 & 0.119193 & 0.950227 \end{matrix} \right]\left[ \begin{matrix} R\\ G \\ B \end{matrix} \right] ⎣ ⎡XYZ⎦ ⎤=⎣ ⎡0.4124530.2126710.0193340.3575800.7151600.1191930.1804230.0721690.950227⎦ ⎤⎣ ⎡RGB⎦ ⎤ X = X X n , X n = 0.950456 X=\frac{X}{X_n},X_n=0.950456 X=XnX,Xn=0.950456 Y = Z Z n , Z n = 1.088754 Y=\frac{Z}{Z_n},Z_n=1.088754 Y=ZnZ,Zn=1.088754 L = { 116 ⋅ Y 1 3 − 16 , Y > 0.008856 903.3 ⋅ Y , e l s e L= \begin{cases} 116\cdot Y^{\frac{1}{3}}-16,\quad Y>0.008856\\ 903.3\cdot Y,\quad else \end{cases} L={116⋅Y31−16,Y>0.008856903.3⋅Y,else 𝑎 = 500 ⋅ 𝑓 ( 𝑋 ) − 𝑓 ( 𝑌 ) + δ 𝑎 = 500 · 𝑓(𝑋) − 𝑓(𝑌) + \delta a=500⋅f(X)−f(Y)+δ 𝑏 = 200 ⋅ 𝑓 ( 𝑌 ) − 𝑓 ( 𝑍 ) + δ 𝑏 = 200 · 𝑓(𝑌) − 𝑓(𝑍) + \delta b=200⋅f(Y)−f(Z)+δ其中, f ( t ) = { t 1 3 , t > 0.008856 7.787 t + 16 , e l s e f(t)= \begin{cases}t^{\frac{1}{3}},\quad t>0.008856\\ 7.787t+\frac{16}{},\quad else \end{cases} f(t)={t31,t>0.0088567.787t+16,else δ = { 128 , 8 位图像 0 , 单精度图像 \delta= \begin{cases}128,8位图像\\ 0,\quad 单精度图像 \end{cases} δ={128,8位图像0,单精度图像取值范围: 𝐿 ∈ [ 0 , 100 ] , a ∈ [ − 127 , 127 ] , 𝑏 ∈ [ − 127 , 127 ] 𝐿 ∈ [0,100],a ∈ [−127,127],𝑏 ∈ [−127,127] L∈[0,100],a∈[−127,127],b∈[−127,127]
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
Lab = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2Lab)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2Lab",Lab)
cv2.waitKey()
cv2.destroyAllWindows()
CIEL*u*v*色彩空间
- CIEL*u*v*色彩空间同 CIEL*a*b*色彩空间一样,都是均匀的颜色模型。CIEL*u*v*色彩空间与设备无关,适用于显示器显示和根据加色原理进行组合的场合,该模型中比较强调对红色的表示,即对红色的变化比较敏感,但对蓝色的变化不太敏感。
- RGB 色彩空间转换到 CIEL*u*v*色彩空间的公式:
- 先从 RGB 色彩空间到 XYZ 色彩空间的转换:
[ X Y Z ] = [ 0.412453 0.357580 0.180423 0.212671 0.715160 0.072169 0.019334 0.119193 0.950227 ] [ R G B ] \left[ \begin{matrix} X\\ Y \\ Z \end{matrix} \right]=\left[ \begin{matrix} 0.412453 & 0.357580 & 0.180423\\ 0.212671 & 0.715160 & 0.072169\\ 0.019334 & 0.119193 & 0.950227 \end{matrix} \right]\left[ \begin{matrix} R\\ G \\ B \end{matrix} \right] ⎣ ⎡XYZ⎦ ⎤=⎣ ⎡0.4124530.2126710.0193340.3575800.7151600.1191930.1804230.0721690.950227⎦ ⎤⎣ ⎡RGB⎦ ⎤- 再从 XYZ 色彩空间到 CIELuv*色彩空间的转换:
L = { 116 ⋅ Y 1 3 − 16 , Y > 0.008856 903.3 ⋅ Y , e l s e L= \begin{cases} 116\cdot Y^{\frac{1}{3}}-16,\quad Y>0.008856\\ 903.3\cdot Y,\quad else \end{cases} L={116⋅Y31−16,Y>0.008856903.3⋅Y,else u ′ = 4 𝑋 𝑋 + 15 𝑌 + 3 𝑍 u^{′}=\frac{4𝑋}{𝑋 + 15𝑌 + 3𝑍} u′=X+15Y+3Z4X v ′ = 9 Y 𝑋 + 15 𝑌 + 3 𝑍 v^{′}=\frac{9Y}{𝑋 + 15𝑌 + 3𝑍} v′=X+15Y+3Z9Y 𝑢 = 13 ⋅ 𝐿 ⋅ ( 𝑢 ′ − 𝑢 𝑛 ) , 𝑢 n = 0.19793943 𝑢 = 13 · 𝐿 · (𝑢^′ − 𝑢_𝑛 ), 𝑢_n =0.19793943 u=13⋅L⋅(u′−un),un=0.19793943 v = 13 ⋅ 𝐿 ⋅ ( v ′ − v 𝑛 ) , v n = 0.46831096 v = 13 · 𝐿 · (v^′ − v_𝑛 ), v_n =0.46831096 v=13⋅L⋅(v′−vn),vn=0.46831096其中, 𝐿 ∈ [ 0 , 100 ] , 𝑢 ∈ [ − 134 , 220 ] , 𝑣 ∈ [ − 140 , 122 ] 𝐿 ∈ [0,100],𝑢 ∈[−134,220],𝑣 ∈ [−140,122] L∈[0,100],u∈[−134,220],v∈[−140,122]
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
Luv = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2Luv)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2Luv",Luv)
cv2.waitKey()
cv2.destroyAllWindows()
Bayer色彩空间
- Bayer 色彩空间(Bayer 模型)被广泛地应用在 CCD 和 CMOS 相机中。它能够从单平面 R、G、B 交错表内获取彩色图像。
- 输出的 RGB 图像的像素点值,是根据当前点的 1 个、2 个或 4 个邻域像素点的相同颜色的像素值获得的。上述模式能够通过移动一个左边的像素或者上方的像素来完成修改。在函数cv2.cvtColor()的色彩空间转换参数中,通常使用两个特定的参数 x 和 y 来表示特定的模式。该模式组成通过上图第二行中的第 2 列与第 3 列的值来指定。
- 可能到这里,有人还是不太明白Bayer色彩空间的原理,在此先略过,后续想到更通俗易懂的解释,再举例说明。
RGBA 色彩空间
- 在 RGB 色彩空间三个通道的基础上,还可以加上一个 A 通道,也叫 alpha 通道,表示透明度。
- 这种 4 个通道的色彩空间被称为 RGBA 色彩空间,PNG 图像是一种典型的 4 通道图像。
- alpha 通道的赋值范围是[0, 1],或者[0, 255],表示从透明到不透明。
import cv2
img1=cv2.imread("1.jpg")
img1_resize=cv2.resize(img1,(400,400))
bgra = cv2.cvtColor(img1_resize, cv2.COLOR_BGR2BGRA)
print('img1_resize.shape:',img1_resize.shape)
print('bgra.shape:',bgra.shape)
cv2.imshow("origin",img1_resize)
cv2.imshow("cv2.COLOR_BGR2BGRA",bgra)
cv2.waitKey()
cv2.destroyAllWindows()
参考文献
[1] https://opencv.org/
[2] 李立宗. Open CV轻松入门:面向Python. 北京: 电子工业出版社,2019
- 更多精彩内容,可点击进入
OpenCV-Python快速入门专栏或我的个人主页查看