当从 RGB 转换为灰度时,据说应该对通道 R、G 和 B 应用特定的权重。这些权重是:0.2989、0.5870、0.1140。
据说这是因为人类对这三种颜色的感知/感受不同。有时也有人说这些是用于计算 NTSC 信号的值。
但是,我在网上没有找到很好的参考资料。这些价值观的来源是什么?
当从 RGB 转换为灰度时,据说应该对通道 R、G 和 B 应用特定的权重。这些权重是:0.2989、0.5870、0.1140。
据说这是因为人类对这三种颜色的感知/感受不同。有时也有人说这些是用于计算 NTSC 信号的值。
但是,我在网上没有找到很好的参考资料。这些价值观的来源是什么?
问题中的具体数字来自 CCIR 601(参见Wikipedia 文章)。
如果你用稍微不同的数字/不同的方法转换 RGB -> 灰度,在正常光照条件下,你在普通电脑屏幕上根本看不到太大差异——试试看。
以下是有关颜色的更多链接:
维基百科亮度
Bruce Lindbloom的杰出网站
Colin Ware 所著的“信息可视化”一书中关于颜色的第 4 章,isbn 1-55860-819-2;book.google.com中指向 Ware 的这个长链接 可能有效,也可能无效
cambridgeincolor:优秀的、编写良好的“关于如何使用强调概念而非程序的视觉导向方法获取、解释和处理数码照片的教程”
如果您遇到“线性”与“非线性”RGB,这是对我自己的旧笔记的一部分。重复一遍,在实践中你不会看到太大的不同。
在色彩科学中,常见的 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
“......渴望感知一致性 [和] 与人类对亮度的感知紧密匹配。” -- 维基百科实验室色彩空间
我发现在对先前类似问题的回答中引用了该出版物。它非常有帮助,该页面有几个示例图像:
Martin Čadík对彩色到灰度图像转换的感知评估,计算机图形学论坛,2008 年第 27 卷
该出版物探讨了其他几种生成具有不同结果的灰度图像的方法:
有趣的是,它得出的结论是,没有普遍最佳的转换方法,因为每种方法的性能都比其他方法好或差,具体取决于输入。
这是 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
}
查看颜色常见问题解答以获取相关信息。这些值来自我们在显示器中使用的 RGB 值的标准化。实际上,根据颜色常见问题解答,您使用的值已经过时,因为它们是用于原始 NTSC 标准而不是现代显示器的值。
这些价值观的来源是什么?
发布的系数的“来源”是 NTSC 规范,可以在Rec601和“电视特征”中看到。
“最终来源”是 CIE 大约 1931 年关于人类颜色感知的实验。人类视觉的光谱响应是不均匀的。实验导致基于感知的三刺激值加权。我们的 L、M 和 S 视锥细胞1对我们识别为“红色”、“绿色”和“蓝色”(分别)的光波长敏感,这就是派生三原色的地方。2
sRGB(和 Rec709)的线性光3光谱权重为:
这些特定于 sRGB 和 Rec709 色彩空间,旨在表示计算机显示器 (sRGB) 或 HDTV 显示器 (Rec709),并在Rec709和BT.2380-2 (10/2018)的 ITU 文档中进行了详细说明
脚注
(1) 视锥细胞是眼睛视网膜的颜色检测细胞。
(2) 然而,所选择的三色光波长不在每个锥体类型的“峰值”处——而是选择三色值,使得它们对特定锥体类型的刺激明显多于另一种,即刺激分离。
(3) 在应用系数之前,您需要对 sRGB 值进行线性化。我在这里的另一个答案中讨论了这个问题。
开始一个列表来列举不同的软件包是如何做到的。这是一篇很好的 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)
nGray = 0.299F * R + 0.587F * G + 0.114F * B;
这些价值观因人而异,尤其是对于色盲的人。
这一切真的有必要吗,人类的感知和CRT vs LCD会有所不同,但RGB强度不会,为什么不L = (R + G + B)/3
将新的RGB设置为L,L,L?