这篇文章是关于处理彩色和灰度图像的混合,并需要将它们转换成统一的格式——全灰度。我们将使用 Pillow、Numpy 和 Matplotlib 包在 Python 中工作。
有时需要将彩色图像转换为灰度图像。当加载在火星表面拍摄的图像作为,高级
神经网络方法的一部分时,就会出现这种需求。我们正在处理彩色和灰度图像的混合,需要将它们转换成统一的格式——全灰度。我们将使用 Pillow、Numpy 和 Matplotlib 包在 Python 中工作。
顺便说一句,这篇文章中所有有趣的信息都来自 于灰度的维基百科条目。
读入彩色图像
使用的 代码 加载 jpeg 图像以供自动编码器用作输入。这是通过使用 Pillow 和 Numpy 完成的:
这会读取图像并将其转换为 Numpy 数组。有关其作用和原因的详细说明,如何将图片转换为数字。对于灰度图像,结果是一个二维数组,其行数和列数等于图像中像素行数和列数。较低的数值表示较深的阴影,较高的数值表示较浅的阴影。像素值的范围通常是 0 到 255。我们除以 255 得到 0 到 1 的范围。
彩色图像表示为三维 Numpy 数组 - 三个二维数组的集合,每个用于红色、绿色和蓝色通道。每一个,就像灰度数组一样,每个像素都有一个值,并且它们的范围是相同的。
Easy Peasy:平均频道
将彩色图像 3D 数组转换为灰度 2D 数组的一种直观方法是,对于每个像素,取红色、绿色和蓝色像素值的平均值以获得灰度值。这将 每个色带贡献的亮度或亮度组合成一个合理的灰度近似值。
该 axis=2 参数告诉 numpy.mean() 所有三个颜色通道的平均值。(axis=0 将平均跨像素行并 axis=1 跨像素列平均。)
嗯,实际上……依赖于通道的亮度感知
在我们看来,绿色看起来比蓝色亮十倍。通过多次重复精心设计的实验,心理学家已经弄清楚我们对亮度或红色、绿色和蓝色的感知有多么不同。他们为我们的通道平均提供了一组不同的权重,以获得总亮度。
嗯,实际上……伽玛压缩
当亮度较低时,我们能够看到微小的差异,但在高亮度水平下,我们对它们的敏感度要低得多。为了避免在高亮度下表现出难以察觉的差异,色阶被扭曲,以便将更多的值集中在范围的低端,而将它们更广泛地分布在高端。这称为伽马压缩。
要在计算灰度亮度之前撤消伽马压缩的影响,有必要应用逆运算,伽马扩展:
伽马压缩的好处是它可以消除平滑变化的深色条纹,就像黄昏时的天空照片一样。不利的一面是,如果我们想做诸如添加、减去或平均频带之类的操作,我们首先必须撤消压缩并将亮度恢复为线性表示。
考虑到伽马压缩后,整个图像都会变亮。它使亮度与原始图像的亮度更接近。最后,我们有一个高质量的灰度表示。
好吧,实际上……线性近似
与我们之前使用的加权平均值相比,伽马解压缩和重新压缩的计算成本相当高。有时速度比尽可能精确的亮度计算更可取。对于这样的情况,有一个线性近似:
这可以让您获得更接近 gamma 压缩校正版本的结果,但无需额外的计算时间。
如您所见,结果一点也不差。它们往往更暗一些,尤其是通过红色的中间值,但可以说在大多数实际方面都一样好。
这种亮度计算方法已编入标准 ITU-R BT.601 Studio 编码参数中,用于标准 4:3 和宽屏幕 16:9 纵横比。 顺便说一句,它在 1983 年获得了艾美奖。
我应该使用哪一个?
如果 close 足够好,或者如果您真的关心速度,请使用伽马校正的线性近似。这是 MATLAB、 Pillow和 OpenCV使用的方法。它包含在我的 Lodgepole 图像和视频处理工具箱中:
但是,如果您只是必须获得最好的结果,请在整个伽马解压缩 - 感知亮度校正 - 伽马重新压缩管道上挥霍:
如果在读到这里之后你坚持直接将三个通道平均起来,我会评判你。
现在去制作漂亮的灰度图像!