【发布时间】:2008-08-18 08:27:32
【问题描述】:
如何将像素的 RGB 值转换为单个单色值?
【问题讨论】:
-
我认为你的意思是灰度。单色意味着图像是一种色调,并且仍然是彩色的。
标签: colors rgb monochrome
如何将像素的 RGB 值转换为单个单色值?
【问题讨论】:
标签: colors rgb monochrome
我在Color FAQ 中找到了一种可能的解决方案。 亮度分量 Y(来自 CIE XYZ 系统)在一个通道中捕捉人类最感知的颜色。所以,使用这些系数:
mono = (0.2125 * color.r) + (0.7154 * color.g) + (0.0721 * color.b);
【讨论】:
将任何基于 RGB 的图片转换为单色的逻辑都不是简单的线性转换。在我看来,这样的问题最好通过“颜色分割”技术来解决。您可以通过 k-means 聚类实现“颜色分割”。
请参阅 MathWorks 网站上的参考示例。
彩色原图。
这是如何工作的?
从整个图像中收集所有像素值。从 W 像素宽和 H 像素高的图像中,您将获得 W *H 颜色值。现在,使用 k-means 算法创建 2 个集群(或箱)并将颜色放入适当的“箱”中。 2 个簇代表您的黑白色调。
演示使用 k-means 进行图像分割的 Youtube 视频? https://www.youtube.com/watch?v=yR7k19YBqiw
这种方法的挑战
k-means 聚类算法容易受到异常值的影响。一些随机像素的 RGB 距离远离人群的其他颜色,很容易使质心倾斜,从而产生意想不到的结果。
【讨论】:
recent scientific article 比较了将彩色照片转换为灰度的最新技术,包括简单的亮度公式和更复杂的技术。
【讨论】:
如前所述,来自 RGB 三元组的灰度转换(请注意,单色图像不必为灰度)取决于口味。
例如,您可以作弊,只提取蓝色分量,只需将红色和绿色分量扔掉,然后复制蓝色值来代替它们。另一个简单且通常可以的解决方案是取像素的 RGB 三元组的平均值,并在所有三个分量中使用该值。
仅适用于 Photoshop 的专业且不是很便宜的灰度/单色转换器插件就有相当大的市场这一事实表明,转换与您希望的一样简单或复杂。
【讨论】:
This MSDN article 使用(0.299 * color.R + 0.587 * color.G + 0.114 * color.B);
This Wikipedia article 使用(0.3* color.R + 0.59 * color.G + 0.11 * color.B);
【讨论】:
这取决于你的动机是什么。如果您只是想将任意图像转换为灰度并让它看起来不错,那么此问题的其他答案中的转换就可以了。
如果您要将彩色照片转换为黑白,则该过程可能非常复杂且主观,需要对每张图像进行特定调整。要了解可能涉及的内容,请查看来自 Adobe for Photoshop 的 tutorial。
在代码中复制这一点相当复杂,并且仍然需要用户干预才能使生成的图像在美学上“完美”(无论这意味着什么!)。
【讨论】:
只是在自选答案中指出,您必须先LINEARIZE sRGB 值,然后才能应用系数。这意味着移除转移曲线。
要去除功率曲线,请将 8 位 R G 和 B 通道除以 255.0,然后使用推荐用于图像处理的sRGB piecewise transform,或者您可以作弊并将每个通道提高到 2.2 的幂。
只有在线性化之后才能应用显示的系数,(在所选答案中也不完全正确)。
标准是0.2126 0.7152和0.0722。将每个通道乘以其系数,然后将它们相加得到 Y,即亮度。然后将 gamma 重新应用到 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);
就是这样。除非你必须解析十六进制字符串......
【讨论】: