我想通过代码(android)完全像上面的图像。但我对这样做的算法感到困惑。我只知道:
对于每个像素:
将 RGB 转换为 HSL
???
将 HSL 转换回 RGB
谁能帮我解释一下第 2 步该怎么做?非常感谢。
ps:我可以通过 ColorMatrix.setSaturation(0) 在 android 中设置饱和度,但结果图像与 Photoshop 不同(因为色调和亮度没有改变?)
我想通过代码(android)完全像上面的图像。但我对这样做的算法感到困惑。我只知道:
对于每个像素:
将 RGB 转换为 HSL
???
将 HSL 转换回 RGB
谁能帮我解释一下第 2 步该怎么做?非常感谢。
ps:我可以通过 ColorMatrix.setSaturation(0) 在 android 中设置饱和度,但结果图像与 Photoshop 不同(因为色调和亮度没有改变?)
您有很多选项可以使图像去饱和。此外请注意,对图像进行去饱和不仅仅是为了使其成为黑白,而且对于某些应用程序,您可能认为它们是等效的。
我用更多细节更新了这篇文章。
这是学生可以将图像转换为灰度的第一件事(至少我过去首先想到的!)它看起来像去饱和:
level = (R + G + B) / 3
它不会产生不好的结果,它快速且易于实施。但它有一个很大的缺点,就是它与人类感知光度的方式不匹配。
第二种方法(亮度有时称为亮度、亮度或强度)是我们眼睛感知亮度方式的更好模型。它基于这样一个事实,即眼睛中的锥体密度在不同颜色中并不均匀。我们对绿色的感知比红色强烈得多,红色比蓝色更强烈。
因为我们不能以相同的强度感知所有颜色,所以平均方法是不准确的(至少它不会产生看起来自然的结果)。如何管理这个?只需使用加权平均值:
level = R * 0.3 + G * 0.59 + B * 0.11
可以想象,有很多关于这些价值观的讨论。最初的 ITU-R 建议提出了这个公式:
level = R * 0.2126 + G * 0.7152 + B * 0.0722
如果我没记错的话,Photoshop 使用它来实现其简单的去饱和功能(是的,它是第一个的不圆角版本):
level = R * 0.299 + G * 0.587 + B * 0.114
无论如何,我认为我们可能不会注意到很多差异,建议最近发生了变化,请在 Wikipedia上查看有关此公式的更多详细信息。
您想了解更多详情吗?阅读 Charles Poynton 的这篇文章:伽玛的康复和他关于这个主题的常见问题解答。
您使用RGB 颜色模型描述了每个像素,但饱和度属于HSL 颜色模型(实际上,在处理饱和度时您可以同时使用 HSL 或 HSV 模型)。请阅读链接以获取有关这些模型的更多详细信息。
去饱和图像包括以下步骤:
让我介绍一下这个过程的一个大的简化:你可以找到RGB的最大值和RGB的最小值之间的中点(亮度,你还记得RGB颜色空间中的颜色是3D中的一个点吗?空间?)。获得去饱和图像的(简化)公式是:
level = (max(R, G, B) + min(R, G, B)) / 2
一种更简单的去饱和形式,有时称为局部最大分解,只需选择每个 RGB 三元组的最大值:
level = max(R, G, B);
正如您可以想象的那样,您可以同时使用局部最大值或局部最小值(我写了局部,因为它搜索每个像素的最小值/最大值)。
不要忘记,您可以以非常快速的方式获得黑白图像(然后看起来像去饱和图像),只需从 RGB 三元组中保留一个通道(例如绿色通道)并将该值复制到所有通道)。
有时 Photoshops 教程不使用它的功能去饱和图像(去饱和功能和调整调色板),但为了获得更好的效果,他们添加了一个具有统一颜色的图层(使用来自亮度部分的值计算)并将该图层与原始图像(搜索教程并复制代码中的步骤)。