问题中的具体数字来自于CCIR 601(参见Wikipedia文章)。
如果你用稍微不同的数字或方法将RGB转换为灰度, 在普通计算机屏幕下,在正常光照条件下,你几乎看不到任何区别——试试吧。
以下是一些关于颜色的链接:
维基百科亮度(Luma)
Bruce Lindbloom的优秀网站
Colin Ware的书《Information Visualization》的第4章,ISBN 1-55860-819-2; Ware在books.google.com 的这个长链接可能可用也可能不可用
cambridgeincolor: 出色、写作精良, “使用以概念为重点而非过程的视觉方法来获取、解释和处理数字照片的教程”
如果你遇到“线性”与“非线性”RGB, 这里是我自己关于此问题的一部分旧笔记。 重申,实际上你几乎看不到什么区别。
在色彩科学中,通常的RGB值,如html rgb(10%,20%,30%), 被称为“非线性”或 伽玛校正。 “线性”值的定义为
Rlin = R^gamma, Glin = G^gamma, Blin = B^gamma
众所周知,许多个人电脑中的 gamma 值为 2.2。
通常情况下,R、G、B 有时被写作 R'、G'、B'(其中 R' = Rlin ^ (1/gamma))。 (纯粹主义者会挑剔这种写法)但在这里,我会将这个标识符省略。
CRT 显示器上的亮度与 RGBlin = RGB ^ gamma 成正比, 因此 CRT 上的 50% 灰色相当暗淡:.5 ^ 2.2 = 最大亮度的22%。 (液晶显示器更加复杂; 此外,一些显卡会补偿 gamma 值。)
要从 RGB 获得称为 L*
的亮度测量值,
首先将 R、G、B 分别除以 255,并计算:
Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma
这是在XYZ颜色空间中的Y
,它是颜色“亮度”的一种度量。(真实公式并不完全是x^gamma,但接近;初步使用x^gamma即可)。
最后,
L* = 116 * Y ^ 1/3 - 16
"...渴望色觉均匀性,并且与人类对亮度的感知非常接近。"-- 维基百科LAB颜色空间
我在之前的类似问题的答案中找到了这篇参考文献,很有帮助,页面包含了几个示例图像:
《颜色转灰度图像的感知评估》,作者Martin Čadík,发表于2008年的《计算机图形学论坛》(Computer Graphics Forum)
该出版物探讨了使用多种方法生成不同结果的灰度图像:
有趣的是,它得出结论:没有普适的最佳转换方法,因为每种方法在输入上的表现都有好坏之分。
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
}
0.11111111 * ((G + (G<<1) + R) <<1) + B)
。这相当于(2*R+6*G+B) / 9)
或0.222 R + 0.666 G + 0.111 B
。在进入生产之前,请将其与各种测试用例的准确公式进行比较。 - ToolmakerSteve请查看颜色常见问题解答,了解相关信息。这些数值来自于我们在显示器中使用的RGB数值的标准化。实际上,根据颜色常见问题解答,您使用的数值已经过时,因为它们是用于原始NTSC标准而不是现代显示器的数值。
这些值的来源是什么?
这些系数的“来源”是可以在Rec601和Characteristics of Television中看到的NTSC规格说明。
“最终来源”是CIE约1931年对人类色彩感知的实验。人类视觉的光谱响应并不均匀。实验导致基于感知加权的三刺激值。我们的L、M和S锥体1对我们所认定为“红色”、“绿色”和“蓝色”的光波长敏感,这就是三刺激值的原色派生的地方。2
sRGB(和Rec709)的线性光3光谱加权如下:
开始一个列表,列举不同软件包的做法。这里还有一篇很好的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与LCD会有所不同,但RGB强度却不会。为什么不使用L = (R + G + B)/3
并将新的RGB设置为L、L、L呢?