原文:
www.kdnuggets.com/2019/12/convert-rgb-image-grayscale.html
有时需要将彩色图像转换为灰度图像。这一需求在加载火星表面拍摄的图像时出现,作为端到端机器学习课程 313,高级神经网络方法的一部分。我们处理了混合的彩色和灰度图像,需要将它们转换为统一的格式——全部为灰度图像。我们将使用 Python,结合 Pillow、Numpy 和 Matplotlib 包。
顺便提一下,本帖子中的所有有趣信息都来自维基百科上的灰度图。(如果你觉得有帮助,也许可以给他们捐一美元。)
1. Google 网络安全证书 - 快速进入网络安全职业轨道。
2. Google 数据分析专业证书 - 提升你的数据分析能力
3. Google IT 支持专业证书 - 支持你的组织的 IT 需求
该代码用于加载 jpeg 图像,供自编码器作为输入。这通过使用 Pillow 和 Numpy 实现:
from PIL import Image
import numpy as np
color_img = np.asarray(Image.open(img_filename)) / 255
这将图像读取并转换为 Numpy 数组。有关此过程的详细描述,请查看上一篇文章:如何将图片转换为数字。对于灰度图像,结果是一个二维数组,行数和列数等于图像的像素行数和列数。较低的数值表示较暗的阴影,较高的数值表示较亮的阴影。像素值的范围通常是 0 到 255。我们将其除以 255,以获得 0 到 1 的范围。
彩色图像表示为三维 Numpy 数组——由三个二维数组组成,分别对应红色、绿色和蓝色通道。每个数组像灰度数组一样,每个像素一个值,其范围相同。
图片来源:黛安·罗赫
将彩色图像 3D 数组转换为灰度 2D 数组的直观方法是,对于每个像素,取红色、绿色和蓝色像素值的平均值以获得灰度值。这将每个颜色通道贡献的亮度或 亮度 合并成一个合理的灰色近似值。
img = numpy.mean(color_img, axis=2)
axis=2
参数告诉 numpy.mean()
对所有三个颜色通道进行平均。 (axis=0
会在像素行之间平均,axis=1
会在像素列之间平均。)
在我们眼中,绿色看起来比蓝色亮大约十倍。通过许多精心设计的实验,心理学家已经弄清楚了我们如何感知红色、绿色和蓝色的亮度差异。他们为我们的通道平均提供了一套不同的权重,以获得总亮度。
结果明显不同,对我来说,更加准确。
当亮度较低时,我们能够看到细微的差异,但在高亮度水平下,我们对这些差异的敏感度要低得多。为了避免在高亮度下浪费精力表示不可察觉的差异,颜色尺度被扭曲,使其在范围的低端集中更多值,而在高端则分布得更广。这就是 gamma 压缩。
在计算灰度亮度之前,为了撤销 gamma 压缩的效果,有必要应用逆操作,即 gamma 扩展:
Gamma 压缩的好处在于它消除了在平滑变化的暗色中出现的带状效果,比如黄昏时天空的照片。缺点是如果我们要做加法、减法或平均值等操作,我们必须先撤销压缩,将亮度恢复为线性表示。
在考虑 gamma 压缩后,图像的亮度得到增强,使其更接近原始图像的亮度。最终,我们得到高质量的灰度表示。
相比于之前我们使用的加权平均,伽马解压和重新压缩的计算成本非常高。有时,速度比尽可能准确的亮度计算更为重要。对于这种情况,有一种线性近似方法:
这可以让你得到一个更接近伽马压缩校正版本的结果,但不需要额外的计算时间。
正如你所看到的,结果一点也不好。它们往往稍显偏暗,尤其是在红色中间值范围,但在大多数实际方面可以说也非常好。
这种亮度计算方法在标准 ITU-R BT.601 Studio encoding parameters of digital television for standard 4:3 and wide screen 16:9 aspect ratios.中进行了规范,该标准在 1983 年获得了艾美奖。
如果接近就足够好,或者你真的关心速度,可以使用伽马校正的线性近似。这是 MATLAB、 Pillow 和 OpenCV 使用的方法。它包含在我的 Lodgepole 图像和视频处理工具箱中:
import lodgepole.image_tools as lit
gray_img = lit.rgb2gray_approx(color_img)
但如果你确实追求最佳结果,可以花费在整个伽马解压 - 视觉亮度校正 - 伽马重新压缩流程上:
import lodgepole.image_tools as lit
gray_img = lit.rgb2gray(color_img)
如果阅读到这里你仍坚持将三个通道直接平均,我会对你做出评判。
现在去制作美丽的灰度图像吧!
原文。经允许转载。
布兰登·罗赫 是 LinkedIn 的高级机器学习工程师。布兰登的专长是创建算法和计算方法。你可以在 这里 找到他的工作实例。