一般图像是有红(R)、绿(G)、蓝(B)三个通道,每个通道由(0-255)不同的值组成,这就构成了多彩的图像,这称为图像的颜色空间。在图像处理中,还有另外的颜色空间(如HSV,HIS),这些更具有可分离性和可操作性。所以很多的图像算法需要将图像从RGB转换为其他空间。
RGB(红绿蓝)是依据人眼识别的颜色定义出的空间,可表示大部分颜色。但在科学研究一般不采用RGB颜色空间,因为它的细节难以进行数字化的调整。它将色调,亮度,饱和度三个量放在一起表示,很难分开。这里先将RGB空间与灰度空间互转。
常见的转换公式如下
算法名称 | 转换公式 |
---|---|
最大值灰度处理 | g r a y = m a x ( R , G , B ) gray=max(R,G,B) gray=max(R,G,B) |
浮点灰度处理 | g r a y = 0.3 R + 0.59 G + 0.11 B gray=0.3R+0.59G+0.11B gray=0.3R+0.59G+0.11B |
整数灰度处理 | g r a y = ( 30 R + 59 G + 11 B ) / 100 gray=(30R+59G+11B)/100 gray=(30R+59G+11B)/100 |
移位灰度处理 | g r a y = ( 28 R + 151 G + 77 B ) > > 8 gray=(28R+151G+77B)>>8 gray=(28R+151G+77B)>>8 |
平均灰度处理 | g r a y = ( R , G , B ) / 3 gray=(R,G,B)/3 gray=(R,G,B)/3 |
加权平均灰度处理 | g r a y = 0.299 R + 0.5877 G + 0.144 B gray=0.299R+0.5877G+0.144B gray=0.299R+0.5877G+0.144B |
灰度化的主旨就是将三通道的色彩转换为一通道的。最常见的是加权平均灰度处理。
得知公式之后,可以直接使用算法将每个像素点的彩色值转换为灰度值。在opencv中有可以直接将RGB图像转换为灰度图像的算法,如下:
#opencv自带方法
img_GRAY = cv2.cvtColor(img_RGB, cv2.COLOR_BGR2GRAY)
#使用numpy转换灰度空间,使用加权平均灰度
height,width,channle = img_GRAY.shape
grayimg = np.zeros((height, width, 3), np.uint8)
#图像加权平均灰度处理方法
for i in range(height):
for j in range(width):
#灰度加权平均法
gray = 0.30 * img[i,j][0] + 0.59 * img[i,j][1] + 0.11 * img[i,j][2]
grayimg[i,j] = np.uint8(gray)
HSV是一种将RGB色彩空间中的点在倒圆锥体中的表示方法。HSV即色相(Hue)、饱和度(Saturation)、明度(Value),又称HSB(B即Brightness)。色相是色彩的基本属性,就是平常说的颜色的名称,如红色、黄色等。饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0-100%的数值。明度(V),取0-max(计算机中HSV取值范围和存储的长度有关)。HSV颜色空间可以用一个圆锥空间模型来描述。圆锥的顶点处,V=0,H和S无定义,代表黑色。圆锥的顶面中心处V=max,S=0,H无定义,代表白色。
这个模型就是按色彩、深浅、明暗来描述的。
H是色彩
S是深浅, S = 0时,只有灰度
V是明暗,表示色彩的明亮程度。
RGB到HSV的转换公式:
V = m a x ( R , G , B ) S = { V − m i n ( R , G , B ) V i f V ≠ 0 0 o t h e r w i s e H = { 60 ( G − B ) / ( V − m i n ( R , G , B ) ) i f V = R 120 + 60 ( B − R ) / ( V − m i n ( R , G , B ) ) i f V = G 240 + 60 ( R − G ) / ( V − m i n ( R , G , B ) ) i f V = B V = max(R,G,B)\\ S = \begin{cases} \frac{V-min(R,G,B)} {V} &if&V\not=0\\ 0& otherwise \end{cases}\\ H = \begin{cases} 60(G-B)/(V-min(R,G,B))&if&V=R\\ 120+60(B-R)/(V-min(R,G,B))&if &V=G\\ 240+60(R-G)/(V-min(R,G,B))&if &V=B \end{cases} V=max(R,G,B)S={VV−min(R,G,B)0ifotherwiseV=0H=⎩⎪⎨⎪⎧60(G−B)/(V−min(R,G,B))120+60(B−R)/(V−min(R,G,B))240+60(R−G)/(V−min(R,G,B))ifififV=RV=GV=B
opencv中提供了RGB转HSV的方法,只需要将原图像传入,输出的即为HSV空间的图像。
img_HSV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV)
在实验过程中发现,opencv直接读取的图片格式为BGR排列的,当转换为RGB时,色彩发生变化,但是使用两种不同的格式生成的HSV空间的图像,结果是一样的。代码如下:
img_BGR = cv2.imread("img.jpg")
cv2.imshow("img_BGR",img_BGR)
# 先将图片转换为RGB格式
img_RGB = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2RGB)
cv2.imshow("img_RGB",img_RGB)
# 使用rgb转换hsv
img_RGB2HSV = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2HSV)
cv2.imshow("img_RGB2HSV",img_RGB2HSV)
# 使用bgr转化hsv
img_BGR2HSV = cv2.cvtColor(img_BGR,cv2.COLOR_BGR2HSV)
cv2.imshow("img_BGR2HSV",img_BGR2HSV)
如上可以知道如何从RGB空间转换为HSV空间了,下边继续记录从HSV空间转换到RGB空间。
当给定一个HSV中的一个值(h,s,v),转换公式如下公式如下
展示的RGB值的范围是0.0到1.0
RGB | HSV |
---|---|
(1,0,0) | (0°,1,1) |
(0.5,1,0.5) | (120°,0.5,1) |
(0,0,0.5) | (240°,1,0.5) |
img_RGB = cv2.cvtColor(img_HSV,cv2.COLOR_HSV2RGB)
hsv图像与上边结果相同,得到的rgb图像如下:
得到的结果是RGB排列的,如果想要还原到原来的样式,还需要进行RGB2BGR操作。