如何将图像转换为灰度?

Way*_*yne 3 hsl rgb android image-processing

我想通过代码(android)完全像上面的图像.但我对这个算法感到困惑.我所知道的是:

每个像素:

  1. 将RGB转换为HSL

  2. ???

  3. 将HSL转换回RGB

任何人都可以向我解释在步骤2中做什么?非常感谢.

ps:我可以通过ColorMatrix.setSaturation(0)在android中设置饱和度,但结果图像与Photoshop不一样(因为Hue和Lightness没有改变?)

Adr*_*tti 10

您有很多选择去饱和图像.另外请注意,去饱和的图像是不是简单地让B&W,但在某些应用中你可能会认为他们是等价的.

我更新了这篇文章的更多细节.

平均

这是学生可以想象的第一件事就是转换成灰度(至少我过去想到的那样!),看起来像是去饱和:

level = (R + G + B) / 3
Run Code Online (Sandbox Code Playgroud)

它不会产生不好的结果,它实现起来快速且容易.但它有一个很大的缺点,就是它与人类感知光度的方式不符.

亮度

第二种方法(Luminance有时被称为Luminosity,Luma或Intensity)是我们的眼睛感知亮度的更好的模型.它基于以下事实:眼睛中的锥体密度在颜色上不均匀.我们比蓝色更强烈地感知绿色比红色和红色更强烈.
因为我们没有感知到具有相同强度的所有颜色,所以平均方法是不准确的(至少它不会产生看起来自然的结果).如何管理?只需使用加权平均值:

level = R * 0.3 + G * 0.59 + B * 0.11
Run Code Online (Sandbox Code Playgroud)

你可以想象有很多关于这些价值观的讨论.ITU-R原始建议提出了这个公式:

level = R * 0.2126 + G * 0.7152 + B * 0.0722
Run Code Online (Sandbox Code Playgroud)

如果我没错,那么Photoshop使用这个简单的去饱和功能(是的,它是第一个的未连接版本):

level = R * 0.299 + G * 0.587 + B * 0.114
Run Code Online (Sandbox Code Playgroud)

我不认为我们最近可能会注意到很多不同的重新更改,请在维基百科上查看有关此公式的更多详细信息.

你想要更多细节吗?阅读Charles Poynton的这篇文章:伽玛的修复和他关于这个主题的常见问题解答.

去饱和

您使用RGB颜色模型描述了每个像素,但饱和度属于HSL颜色模型(实际上,使用饱和度时,您可以使用HSL或HSV模型).有关这些型号的更多详细信息,请阅读链接.

对图像进行去饱和包括以下步骤:

  • 将每个像素从RGB转换为HSL(如果需要详细信息,请参阅此文章).
  • 强制饱和度为零(这应该是什么setSaturation(0))
  • 将其转换回RGB(请参阅此书签).

让我介绍一下这个过程的一个很大的简化:你可以去寻找一个颜色,找到最大RGB和最小RGB之间的中点(亮度,你还记得RGB颜色空间中的一个颜色是3D中的一个点吗?空间?).获得去饱和图像的(简化)公式是:

level = (max(R, G, B) + min(R, G, B)) / 2
Run Code Online (Sandbox Code Playgroud)

分解

一种更简单的去饱和形式,有时称为局部最大分解,只需选择每个RGB三元组的最大值:

level = max(R, G, B);
Run Code Online (Sandbox Code Playgroud)

你可以想象你可以使用局部最大值或局部最小值(我写了本地因为它搜索每个像素的最小值/最大值).

其他方法

不要忘记,您可以以非常快的方式获得黑白图像(然后看起来像去饱和图像的东西),只需保留RGB三元组中的单个通道(例如绿色通道)并将该值复制到所有通道).

有时Photoshops教程不使用其功能去饱和图像(去饱和度函数和调整调色板),但为了获得更好的效果,他们添加了一个具有均匀颜色的图层(使用亮度部分的值计算),并且他们将该图层与原始图像(搜索代码中的步骤教程和repro).