将RGB转换为灰度/强度

ypn*_*nos 119 language-agnostic rgb colors image-processing computer-vision

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

据说,其原因是人类对这三种颜色的感知/敏感性不同.有时也会说这些是用于计算NTSC信号的值.

但是,我没有在网上找到这方面的好参考.这些价值观的来源是什么?

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

den*_*nis 82

问题中的具体数字来自CCIR 601(参见下面的维基百科链接).

如果您使用稍微不同的数字/不同方法转换RGB - >灰度,在正常光照条件下,您在普通计算机屏幕上看不到多少差异 - 试试吧.

以下是一些关于颜色的更多链接:

维基百科Luma

Bruce Lindbloom的优秀网站

Colin Ware撰写的第4章"信息可视化",isbn 1-55860-819-2; 这个与books.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
Run Code Online (Sandbox Code Playgroud)

许多PC的gamma为2.2.通常的RGB有时被写为R'G'B'(R'= Rlin ^(1/gamma))(纯粹的舌头咔哒声),但在这里我会放弃'.

CRT显示器上的亮度与RGBlin = RGB ^ gamma成比例,因此CRT上的50%灰度非常暗:.5 ^ 2.2 =最大亮度的22%.(LCD显示屏更复杂;此外,一些显卡可以补偿伽玛.)

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

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma
Run Code Online (Sandbox Code Playgroud)

这是Y在XYZ色彩空间; 它是颜色"亮度"的量度.(真正的公式不完全是x ^ gamma,但是接近;第一次通过坚持使用x ^ gamma.)

最后,

L* = 116 * Y ^ 1/3 - 16
Run Code Online (Sandbox Code Playgroud)

"...渴望感性统一[和]与人类对轻盈的感知紧密相关." - 维基百科实验室色彩空间

  • Y = 0.2126*R + 0.7152*G + 0.0722*B - 维基百科(http://en.wikipedia.org/wiki/Grayscale) (8认同)

ypn*_*nos 12

我发现该出版物在对先前类似问题的回答中引用.这非常有帮助:

http://cadik.posvete.cz/color_to_gray_evaluation/

它显示了"吨"的不同方法来生成具有不同结果的灰度图像!


twe*_*ter 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
        }
Run Code Online (Sandbox Code Playgroud)

  • @twerdster 两组系数都不正确。.3,.6,.11 是旧的 NTSC 标准,而不是 sRGB/Rec709(这是网络和大多数计算机使用的)。而你的 0.25,0.5,0.25 并不是一个合理的权衡——B 只是亮度的 7%,你错了 347%。sRGB/r709 的系数(线性化后):__Rlin * 0.2126 + Glin * 0.7152 + Blin * 0.0722 = Y__ 这些光谱权重来自人类光谱感知。你不能只是为了方便而随意输入任何你想要的数字,并希望是准确的。您需要线性化 sRGB,然后应用正确的系数。 (3认同)
  • 0.3 0.6 0.11不加1。维基百科似乎建议0.30 0.59 0.11。 (2认同)

Bri*_*ell 6

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