141

当从 RGB 转换为灰度时,据说应该对通道 R、G 和 B 应用特定的权重。这些权重是:0.2989、0.5870、0.1140。

据说这是因为人类对这三种颜色的感知/感受不同。有时也有人说这些是用于计算 NTSC 信号的值。

但是,我在网上没有找到很好的参考资料。这些价值观的来源是什么?

另请参阅这些先前的问题:此处此处

4

8 回答 8

92

问题中的具体数字来自 CCIR 601(参见Wikipedia 文章)。

如果你用稍微不同的数字/不同的方法转换 RGB -> 灰度,在正常光照条件下,你在普通电脑屏幕上根本看不到太大差异——试试看。

以下是有关颜色的更多链接:

维基百科亮度

Bruce Lindbloom的杰出网站

Colin Ware 所著的“信息可视化”一书中关于颜色的第 4 章,isbn 1-55860-819-2;book.google.com中指向 Ware 的这个长链接 可能有效,也可能无效

cambridgeincolor:优秀的、编写良好的“关于如何使用强调概念而非程序的视觉导向方法获取、解释和处理数码照片的教程”

如果您遇到“线性”与“非线性”RGB,这是对我自己的旧笔记的一部分。重复一遍,在实践中你不会看到太大的不同。


### RGB -> ^gamma -> Y -> L*

在色彩科学中,常见的 RGB 值,如 html rgb(10%, 20%, 30%),被称为“非线性”或 Gamma 校正。“线性”值定义为

Rlin = R^gamma,  Glin = G^gamma,  Blin = B^gamma

对于许多 PC,其中 gamma 为 2.2。通常的 RGB 有时写为 R' G' B' (R' = Rlin ^ (1/gamma)) (纯粹主义者舌头点击)但在这里我会放弃'。

CRT 显示器上的亮度与 RGBlin = RGB ^ gamma 成正比,因此 CRT 上 50% 的灰色非常暗:0.5 ^ 2.2 = 最大亮度的 22%。(LCD 显示器更复杂;此外,一些显卡会补偿伽马。)

要获得L*从 RGB 调用的亮度度量,首先将 RGB 除以 255,然后计算

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma

这是Y在 XYZ 颜色空间中;它是颜色“亮度”的量度。(真正的公式并不完全是 x^gamma,而是接近;坚持使用 x^gamma 进行第一遍。)

最后,

L* = 116 * Y ^ 1/3 - 16

“......渴望感知一致性 [和] 与人类对亮度的感知紧密匹配。” -- 维基百科实验室色彩空间

于 2009-03-27T12:16:22.087 回答
16

我发现在对先前类似问题的回答中引用了该出版物。它非常有帮助,该页面有几个示例图像:

Martin Čadík对彩色到灰度图像转换的感知评估,计算机图形学论坛,2008 年第 27 卷

该出版物探讨了其他几种生成具有不同结果的灰度图像的方法:

  • CIE Y
  • 颜色2灰色
  • 脱色
  • 史密斯08
  • 拉舍05
  • 巴拉04
  • 纽曼07

有趣的是,它得出的结论是,没有普遍最佳的转换方法,因为每种方法的性能都比其他方法好或差,具体取决于输入。

于 2009-03-26T21:54:23.437 回答
9

这是 c 中的一些代码,用于将 rgb 转换为灰度。用于 rgb 到灰度转换的实际权重是 0.3R+0.6G+0.11B。这些权重并不是绝对重要的,因此您可以使用它们。我把它们做成了 0.25R+ 0.5G+0.25B。它会产生稍暗的图像。

注意:以下代码假定 xRGB 32 位像素格式

unsigned int *pntrBWImage=(unsigned int*)..data pointer..;  //assumes 4*width*height bytes with 32 bits i.e. 4 bytes per pixel
unsigned int fourBytes;
        unsigned char r,g,b;
        for (int index=0;index<width*height;index++)
        {
            fourBytes=pntrBWImage[index];//caches 4 bytes at a time
            r=(fourBytes>>16);
            g=(fourBytes>>8);
            b=fourBytes;

            I_Out[index] = (r >>2)+ (g>>1) + (b>>2); //This runs in 0.00065s on my pc and produces slightly darker results
            //I_Out[index]=((unsigned int)(r+g+b))/3;     //This runs in 0.0011s on my pc and produces a pure average
        }
于 2011-01-30T00:18:18.397 回答
6

查看颜色常见问题解答以获取相关信息。这些值来自我们在显示器中使用的 RGB 值的标准化。实际上,根据颜色常见问题解答,您使用的值已经过时,因为它们是用于原始 NTSC 标准而不是现代显示器的值。

于 2009-03-26T19:51:20.330 回答
3

这些价值观的来源是什么?

发布的系数的“来源”是 NTSC 规范,可以在Rec601“电视特征”中看到。

“最终来源”是 CIE 大约 1931 年关于人类颜色感知的实验。人类视觉的光谱响应是不均匀的。实验导致基于感知的三刺激值加权。我们的 L、M 和 S 视锥细胞1对我们识别为“红色”、“绿色”和“蓝色”(分别)的光波长敏感,这就是派生三原色的地方。2

sRGB(和 Rec709)的线性光3光谱权重为:

R* 0.2126 + G* 0.7152 + B* 0.0722 = Y

这些特定于 sRGB 和 Rec709 色彩空间,旨在表示计算机显示器 (sRGB) 或 HDTV 显示器 (Rec709),并在Rec709BT.2380-2 (10/2018)的 ITU 文档中进行了详细说明

脚注 (1) 视锥细胞是眼睛视网膜的颜色检测细胞。
(2) 然而,所选择的三色光波长不在每个锥体类型的“峰值”处——而是选择三色值,使得它们对特定锥体类型的刺激明显多于另一种,即刺激分离。
(3) 在应用系数之前,您需要对 sRGB 值进行线性化。我在这里的另一个答案中讨论了这个问题。

于 2019-05-20T05:15:29.400 回答
0

开始一个列表来列举不同的软件包是如何做到的。这是一篇很好的 CVPR 论文,也可以阅读

免费图片

#define LUMA_REC709(r, g, b)    (0.2126F * r + 0.7152F * g + 0.0722F * b)
#define GREY(r, g, b) (BYTE)(LUMA_REC709(r, g, b) + 0.5F)

开放式CV

nVidia 性能基元

英特尔性能原语

MATLAB

nGray =  0.299F * R + 0.587F * G + 0.114F * B; 
于 2021-03-24T15:25:16.430 回答
-4

这些价值观因人而异,尤其是对于色盲的人。

于 2016-08-18T01:04:03.037 回答
-7

这一切真的有必要吗,人类的感知和CRT vs LCD会有所不同,但RGB强度不会,为什么不L = (R + G + B)/3将新的RGB设置为L,L,L?

于 2018-03-13T13:45:05.180 回答