Python图像处理入门100题之灰度化
前言
这是一个新的专题!
题来自于「画像処理100本ノック」中文版本!为图像处理初学者设计的 100 个问题。
在这里我们可以学到:
1、Python的第三方库OpenCV和matplotlib的基本用法
2、数字图像处理的基本算法
问题二:灰度化
将图像灰度化
灰度是一种图像亮度的表示方法,通过下式计算: Y = 0.2126 R + 0.7152 G + 0.0722 B Y = 0.2126\ R + 0.7152\ G + 0.0722\ B Y=0.2126 R+0.7152 G+0.0722 B
原始图片可以在上面的GitHub链接里找到。
代码实现:
1.准备工作
(1)图像灰度化意义
灰度化:将多通道的彩色图像转换为单通道的灰度图像的过程。
灰度范围为0-255,0为纯黑,255为纯白。
灰度化的好处是:相较于彩色图像灰度图像占内存更小,运行速度更快;灰度图像后可以在视觉上增加对比,突出目标区域。
(2)图像灰度化处理方法
图像灰度化处理有三种常用方法:最大值法、平均值法和加权平均法。
(1)最大值法
最大值法,即直接取R,B,G三个分量中数值最大的分量的数值(0视为最小,255视为最大)。公式为:
Y
=
m
a
x
(
R
,
G
,
B
)
Y=max(R,G,B)
Y=max(R,G,B)
(2)平均值法
平均值法,即取R,B,G三个分量中数值的均值。公式为:
R
=
G
=
B
=
(
R
+
G
+
B
)
/
3
R=G=B=(R+G+B)/3
R=G=B=(R+G+B)/3
(3)加权平均法(也是作者使用的方法)
根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像:
Y
=
0.2126
R
+
0.7152
G
+
0.0722
B
Y = 0.2126\ R + 0.7152\ G + 0.0722\ B
Y=0.2126 R+0.7152 G+0.0722 B
2.灰度化
平均值法代码如下(示例):
import cv2
import numpy as np
# Gray scale
def BGR2GRAY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
out = 1/3 * b + 1/3 * g + 1/3 * r
# out = 1/3 * (b + g + r) # 以上两行代码看似效果相等,实际运行起来却不一样,各位读者请先自行思考一下,我们会在后期的博客里解读
out = out.astype(np.uint8)
return out
# Read image
img = cv2.imread("imori.jpg")
# Grayscale
out = BGR2GRAY(img)
# Save result
cv2.imwrite("out.jpg", out)
cv2.namedWindow("result",0)
cv2.resizeWindow("result", 200, 200)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示:
加权平均法代码如下(作者源码):
import cv2
import numpy as np
# Gray scale
def BGR2GRAY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
out = 0.2126 * r + 0.7152 * g + 0.0722 * b # 加权处理
out = out.astype(np.uint8)
return out
# Read image
img = cv2.imread("imori.jpg")
# Grayscale
out = BGR2GRAY(img)
# Save result
cv2.imwrite("out.jpg", out)
cv2.namedWindow("result",0)
cv2.resizeWindow("result", 200, 200)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示:
总结
用了三种方式做了一个彩色图像转灰度图像的转换,我们发现在前两种方法,在out的最后输出上有一个astype的操作,最后out的数据类型变成了unit8,是因为OpenCV只能表示unit8型的数据,可以尝试如果为浮点型cv.imshow()是显示不了图片的