将RGB转换为灰度/强度

时间:2009-03-26 19:39:07

标签: colors language-agnostic rgb

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

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

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

另请参阅以前的这些问题:herehere

9 个答案:

答案 0 :(得分:78)

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

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

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

维基百科Luma

Bruce Lindbloom优秀的网站

Colin Ware着作中关于色彩的第4章,“信息可视化”,isbn 1-55860-819-2; books.google.com中与Ware的长链接 可能会也可能不会起作用

cambridgeincolor: 优秀,写得很好 “有关如何获取,解释和处理数码照片的教程 使用视觉导向的方法,强调概念而不是程序“

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

<小时/>

RGB - &gt; ^ gamma - &gt; Y - &gt; L *

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

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

许多PC的gamma为2.2。 通常的R G B有时写成R'G'B'(R'= Rlin ^(1 / gamma)) (纯粹的舌头点击)但在这里我会放弃'。

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

要从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 color space

答案 1 :(得分:10)

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

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

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

答案 2 :(得分: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
        }

答案 3 :(得分:6)

这是一篇关于如何推导出这些数字(或类似数字)的论文:

https://web.archive.org/web/20160303201512/http://www.cis.rit.edu/mcsl/research/broadbent/CIE1931_RGB.pdf

答案 4 :(得分:6)

查看Color FAQ以获取相关信息。这些值来自我们在显示器中使用的RGB值的标准化。实际上,根据Color FAQ,您使用的值已经过时,因为它们是用于原始NTSC标准而非现代监视器的值。

答案 5 :(得分:1)

  

这些值的来源是什么?

发布的系数的“来源”是NTSC规范,可以在Rec601Characteristics of Television中看到。

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

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

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

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

脚注 (1)视锥细胞是眼睛视网膜的颜色检测细胞。
(2)但是,所选的三刺激波长不在每种锥体类型的“峰值”处-而是选择三刺激值,以使它们对特定锥体类型的刺激比对另一种锥体类型的刺激要大得多,即刺激的分离。
(3)在应用系数之前,您需要线性化sRGB值。我在another answer here.

中对此进行了讨论

答案 6 :(得分:0)

开始一个列表来列举不同的软件包是如何做到的。 Here is a good CVPR paper to read as well

FreeImage

#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)

OpenCV

nVidia Performance Primitives

Intel Performance Primitives

Matlab

nGray =  0.299F * R + 0.587F * G + 0.114F * B; 

答案 7 :(得分:-1)

这些值因人而异,特别是对于色盲的人。

答案 8 :(得分:-3)

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