彩色图像转灰度图像
数字图像
现在我们所接触到的图像绝大多数都是数字图像,图像数字化后,每个像素点就可以看作是一个小方格,每个小方格里面存储的就是图像的像素信息。如果把一副数字图像抽象出来,就是一个二维矩阵(灰度图)或者三维矩阵(彩色图)。
彩色图像
任何颜色都有红、绿、蓝三原色组成。用红、绿、蓝三元组的二维矩阵来表示(这样构成了三个通道),抽象出来一起构成了一个三维数组。三元组的每个数值也是在0-255之间,0表示相应的基色在该像素中没有,而255表示相应的基色在该像素中取得最大值。通过调节每个通道数灰度值的亮度,从而对三个通道中的三种基色进行不同搭配,进而构成了五颜六色的彩色世界!!我们可以把这三种基色(红、绿、蓝)看成三种颜料,每一个颜色通道里面的灰度等级看成每种颜料的调色板,灰度等级越大,那么对应的通道中的颜色就越接近三种基色。例如一个8bit的彩色图片,灰度等级为0~255,如果第0通道(R)里面灰度等级为255,这个通道显示的色板就是红色,如果灰度等级小于255,那个红色就会越来越淡,到0的时候就表示红色这个基色在0通道里面没有了,依次类推,第1通道(G)、第2通道(B)也是这个原理,然后将这三种色板的基色重叠在一起,就好比三种基色颜料混合在一起,这样就构成了彩色图像。彩色图像的几何空间解释
灰度图像
每个像素的亮度用一个数值来表示,取值范围0-255,0表示黑、255表示白,其他值表示处于黑白之间的灰度,抽象出来构成了一个二维数组。灰度图像就没有色彩了,他的颜色是介于黑色到白色。255表示白色,0表示黑色,灰度等级处于之间就表示成不同等级的灰色。
转换
彩色图像转换成灰度图像最基本的就是考虑怎么去分配三个通道里面的灰度等级,如果单纯直接将R通道里面的灰度值全部拿出来,也会构成一个灰度图像,同理,拿出G通道、B通道的拿出来,也是一副灰度图像,但是我们一般不这样做。查阅官方手册后,我们可以思考,通过以下几种方法来转换彩色图像的三个通道的灰度值:
- 浮点算法:Gray=0.299R+0.587G+0.114B
- 整数方法:Gray=(R30+G59+B*11)/100
- 移位方法:Gray=(R28+G151+B*77)>>8
- 平均值法:Gray=(R+G+B)/3
- 最大值法:Gray = max(R,G,B)
- 最小值法:Gray = min(R,G,B)
- 仅取绿色:Gray=G
上面公式中的R、G、B表示这三个通道里面的灰度值。为什么会出现这样不同的比例转换呢?因为我们人的眼睛对颜色的敏感程度是不一样的,我们对绿色更加敏感,其次是红色,最后是蓝色。所以对不同通道里的灰度值进行加权,加权后得到的灰度值就是我们转换后的灰度图的灰度值,所以这样得到的灰度图像更符合我们人眼的直观映像。转换后存到对应的二维数组里面,这个数组就是转换后的灰度图像抽象意义上的二维数组,显示出来就是一副灰度图像。这就是彩色图像转换成灰度图像的原理。
下面给出一种转换方式的python代码实现:
import numpy as np
import cv2
def color2gray(color_img):
size_h, size_w, channel = color_img.shape
gray_img = np.zeros((size_h, size_w), dtype=np.uint8)
for i in range(size_h):
for j in range(size_w):
gray_img[i, j] = round((color_img[i, j, 0]*30 + color_img[i, j, 1]*59 +\
color_img[i, j, 2]*11)/100)
return gray_img
if __name__ == '__main__':
pic = cv2.imread('./pic/eye.png')
pic_gray = color2gray(pic) # 得到其灰度图像
cv2.imshow('origin picture', pic)
cv2.imshow('gray picture', pic_gray)
cv2.waitKey()
使用这种方法转换后的结果: