如何将像素的 RGB 值转换为单个单色值?
7 回答
我在颜色常见问题解答中找到了一种可能的解决方案。亮度分量Y(来自CIE XYZ 系统)在一个通道中捕获人类最感知的颜色。所以,使用这些系数:
mono = (0.2125 * color.r) + (0.7154 * color.g) + (0.0721 * color.b);
这篇最近的科学文章比较了将彩色照片转换为灰度的最新技术,包括简单的亮度公式和更复杂的技术。
这篇 MSDN 文章使用(0.299 * color.R + 0.587 * color.G + 0.114 * color.B);
这篇维基百科文章使用(0.3* color.R + 0.59 * color.G + 0.11 * color.B);
这取决于你的动机是什么。如果您只想将任意图像转换为灰度并让它看起来不错,那么此问题的其他答案中的转换就可以了。
如果您要将彩色照片转换为黑白,则该过程可能非常复杂且主观,需要对每张图像进行特定调整。要了解可能涉及的内容,请查看 Adobe for Photoshop 的本教程。
在代码中复制这一点相当复杂,并且仍然需要用户干预才能获得美学上“完美”的结果图像(无论这意味着什么!)。
如前所述,来自 RGB 三元组的灰度转换(请注意,单色图像不必是灰度的)取决于口味。
例如,您可以作弊,只提取蓝色分量,只需将红色和绿色分量扔掉,然后复制蓝色值来代替它们。另一个简单且通常可以的解决方案是取像素的 RGB 三元组的平均值,并在所有三个分量中使用该值。
仅用于 Photoshop 的专业且不是很便宜的灰度/单色转换器插件就有相当大的市场这一事实表明,转换与您希望的一样简单或复杂。
将任何基于 RGB 的图片转换为单色的逻辑都不是简单的线性变换。在我看来,这样的问题最好通过“颜色分割”技术来解决。您可以通过 k-means 聚类实现“颜色分割”。
请参阅 MathWorks 网站上的参考示例。
原图彩色。
这是如何运作的?
从整个图像中收集所有像素值。从 W 像素宽和 H 像素高的图像中,您将获得 W *H 颜色值。现在,使用 k-means 算法创建 2 个集群(或箱)并将颜色放入适当的“箱”中。2 个簇代表您的黑白色调。
Youtube 视频演示使用 k-means 进行图像分割? https://www.youtube.com/watch?v=yR7k19YBqiw
这种方法的挑战
k-means 聚类算法容易受到异常值的影响。RGB 距离远离其他人群的颜色的一些随机像素很容易使质心倾斜,从而产生意想不到的结果。
只是为了在自选答案中指出,您必须先线性化 sRGB 值,然后才能应用系数。这意味着移除转移曲线。
要去除功率曲线,请将 8 位 RG 和 B 通道除以 255.0,然后使用推荐用于图像处理的sRGB 分段变换,或者您可以作弊并将每个通道提高到 2.2 的幂。
只有在线性化之后才能应用显示的系数(在所选答案中也不完全正确)。
标准是0.2126 0.7152和0.0722。将每个通道乘以其系数,然后将它们相加得到 Y,即亮度。然后将伽玛重新应用到 Y 并乘以 255,然后复制到所有三个通道,然后你就有了一个灰度(单色)图像。
这一切都在一个简单的行中:
// Andy's Easy Greyscale in one line.
// Send it sR sG sB channels as 8 bit ints, and
// it returns three channels sRgrey sGgrey sBgrey
// as 8 bit ints that display glorious grey.
sRgrey = sGgrey = sBgrey = Math.min(Math.pow((Math.pow(sR/255.0,2.2)*0.2126+Math.pow(sG/255.0,2.2)*0.7152+Math.pow(sB/255.0,2.2)*0.0722),0.454545)*255),255);
就是这样。除非你必须解析十六进制字符串......