可见光谱的RGB值

sor*_*h-r 40 algorithm rgb

我需要一种算法或函数来将可见光谱范围的每个波长映射到其等效的RGB值.RGB系统和灯的波长之间是否存在任何结构关系?喜欢这个图像: 替代文字http://www1.appstate.edu/~kms/classes/psy3203/Color/spectrum5.gif 抱歉,如果这是无关紧要的: - ]

Spe*_*tre 39

我最近发现我的光谱颜色不能正常工作,因为它们基于非线性和移位数据.所以我做了很少的研究和数据编译,发现那里的大多数光谱图像是不正确的.此外,色彩范围不匹配给对方,所以我从这点只用线性化的真实光谱数据这样

这是我的整顿产量:

光谱颜色

  • 第一个光谱是我发现的最佳渲染光谱,但仍然远离真实的光谱
  • 第二个是从地球上取下太阳的线性光谱
  • 最后一个是我目前的颜色输出

以下是RGB图:

这是两个图的合并:

图合并

现在的代码:

void spectral_color(double &r,double &g,double &b,double l) // RGB <0,1> <- lambda l <400,700> [nm]
    {
    double t;  r=0.0; g=0.0; b=0.0;
         if ((l>=400.0)&&(l<410.0)) { t=(l-400.0)/(410.0-400.0); r=    +(0.33*t)-(0.20*t*t); }
    else if ((l>=410.0)&&(l<475.0)) { t=(l-410.0)/(475.0-410.0); r=0.14         -(0.13*t*t); }
    else if ((l>=545.0)&&(l<595.0)) { t=(l-545.0)/(595.0-545.0); r=    +(1.98*t)-(     t*t); }
    else if ((l>=595.0)&&(l<650.0)) { t=(l-595.0)/(650.0-595.0); r=0.98+(0.06*t)-(0.40*t*t); }
    else if ((l>=650.0)&&(l<700.0)) { t=(l-650.0)/(700.0-650.0); r=0.65-(0.84*t)+(0.20*t*t); }
         if ((l>=415.0)&&(l<475.0)) { t=(l-415.0)/(475.0-415.0); g=             +(0.80*t*t); }
    else if ((l>=475.0)&&(l<590.0)) { t=(l-475.0)/(590.0-475.0); g=0.8 +(0.76*t)-(0.80*t*t); }
    else if ((l>=585.0)&&(l<639.0)) { t=(l-585.0)/(639.0-585.0); g=0.84-(0.84*t)           ; }
         if ((l>=400.0)&&(l<475.0)) { t=(l-400.0)/(475.0-400.0); b=    +(2.20*t)-(1.50*t*t); }
    else if ((l>=475.0)&&(l<560.0)) { t=(l-475.0)/(560.0-475.0); b=0.7 -(     t)+(0.30*t*t); }
    }
//--------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

哪里

  • l 是[nm]可用值的波长 l = < 400.0 , 700.0 >
  • r,g,b 正在返回范围内的颜色分量 < 0.0 , 1.0 >

  • 第一段中的“像这样”链接已失效。不再加载:https://www.cfa.harvard.edu/ssp/images/SolarCCD.jpg(未找到)。 (2认同)
  • @SohailSi 感谢您注意到我,我从我的存档中添加了较低质量的图像(原始图像按相反顺序排列,大小为 2.9MByte jpg,超出了 imgur 2MByte 限制,因此无法发布) (2认同)

Ian*_*oyd 11

将波长转换为 RGB 颜色

首先,您查阅CIE 1964 补充标准色度观察者图表存档

https://imgur.com/a/JDatZNm

并查找所需波长的CIE 颜色匹配函数值。

例如,我想获得 455 nm 光的颜色:

在此处输入图片说明

对于我们想要的波长:

| nm  | CIE color matching functions  |  Chromacity coordinates     |
| nm  |     X    |     Y    |    Z    |    x    |    y    |    z    |
|-----|----------|----------|---------|---------|---------|---------| 
| 455 | 0.342957 | 0.106256 | 1.90070 | 0.14594 | 0.04522 | 0.80884 |
Run Code Online (Sandbox Code Playgroud)

注意:色度坐标是根据 CIE 颜色匹配函数简单计算出来的:

x = X / (X+Y+Z)
y = Y / (X+Y+Z)
z = Z / (Z+Y+Z)
Run Code Online (Sandbox Code Playgroud)

鉴于:

X+Y+Z = 0.342257+0.106256+1.90070 = 2.349913
Run Code Online (Sandbox Code Playgroud)

我们计算:

x = 0.342257 / 2.349913 = 0.145945
y = 0.106256 / 2.349913 = 0.045217
z = 1.900700 / 2.349913 = 0.808838
Run Code Online (Sandbox Code Playgroud)

您使用两种不同的颜色空间指定了 455 nm 光:

  • XYZ: (0.342957, 0.106256, 1.900700)
  • xyz: (0.145945, 0.045217, 0.808838)

我们还可以添加第三个颜色空间:xyY

x = x = 0.145945
y = y = 0.045217
Y = y = 0.045217
Run Code Online (Sandbox Code Playgroud)

我们现在在 3 个不同的颜色空间中指定了 455 nm 的光:

  • XYZ: (0.342957, 0.106256, 1.900700)
  • xyz: (0.145945, 0.045217, 0.808838)
  • xyY: (0.145945, 0.045217, 0.045217)

因此,我们已将纯单色发射光的波长转换为XYZ颜色。现在我们要将其转换为 RGB。

如何将 XYZ 转换为 RGB?

XYZxyzxyY是使用绝对物理描述颜色的绝对颜色空间。

同时,人们使用的每一个实用的色彩空间:

  • 实验室
  • HSV
  • HSL
  • RGB

取决于一些白点。然后将颜色描述为相对于该白点。

例如,

  • RGB 白色 (255,255,255) 表示“白色”
  • Lab white (100, 0, 0) 表示“白色”
  • LCH white (100, 0, 309) 表示“白色”
  • HSL white (240, 0, 100) 表示“白色”
  • HSV 白色 (240, 0, 100) 表示“白色”

但是没有像白色这样的颜色。你如何定义白色?阳光的颜色?

  • 在一天中的什么时候?
  • 有多少云层?
  • 在什么纬度?
  • 在地球上?

有些人使用他们(可怕的橙色)白炽灯泡的白色来表示白色。有些人使用荧光灯的颜色。白色没有绝对的物理定义——白色存在于我们的大脑中。

所以我们必须选择白色

我们必须选择白色。(真的必须选择白色。)还有很多白色可供选择:

我会为你挑选一件白色的。sRGB 使用的相同白色:

  • D65 - 北欧晴朗夏日的日光照明

D65(它的颜色接近 6504K,但不完全是因为地球的大气层),具有以下颜色:

  • XYZ_D65: (0.95047, 1.00000, 1.08883)

有了它,您可以将您的转换XYZLab(或Luv) - 一个同样能够表达所有理论颜色的颜色空间。现在我们有了 445 nm 单色光发射的第 4 色空间表示:

  • XYZ: (0.342957, 0.106256, 1.900700)
  • xyz: (0.145945, 0.045217, 0.808838)
  • xyY: (0.145945, 0.045217, 0.045217)
  • 实验室: (38.94259, 119.14058, -146.08508) (假设 d65)

但你想要RGB

Lab(和Luv) 是相对于某个白点的颜色空间。即使您被迫选择一个任意的白点,您仍然可以表示每种可能的颜色。

RGB 不是那样的。使用 RGB:

  • 颜色不仅是相对于某些白点
  • 但也是相对于三基色:红、绿、蓝

如果您将 RGB 颜色指定为 (255, 0, 0),则表示您想要“只是红色”。但是没有红色的定义。没有“红”、“绿”或“蓝”之类的东西。彩虹是连续的,没有箭头说:

这是红色的

这再次意味着我们必须三挑三原色。您必须选择三种原色来说明“红色”、“绿色”和“蓝色”是什么。同样,您有许多不同的红色、绿色、蓝色定义可供选择:

  • CIE 1931
  • ROMM RGB
  • Adobe 广色域 RGB
  • DCI-P3
  • NTSC (1953)
  • 苹果RGB
  • sRGB
  • 日本NTSC
  • PAL/SECAM
  • 土坯RGB 98
  • 单色RGB

我给你挑。我会选择这三种颜色:

  • 红色:xyY = (0.6400, 0.3300, 0.2126)
  • 绿色:xyY = (0.3000, 0.6000, 0.7152)
  • 蓝色: xyY = (0.1500, 0.0600, 0.0722)

这些也是 1996 年国际委员会选择的初选。

他们创建了一个标准,说每个人都应该使用:

  • 白点:D65 日光
  • 红色: (0.6400, 0.3300, 0.2126)
  • 绿色: (0.3000, 0.6000, 0.7152)
  • 蓝色:(0.1500、0.0600、0.0722)

他们称之为标准sRGB

最后的推

现在我们选择了我们的

  • 白点
  • 三个初选

我们现在可以将您的 XYZ 颜色转换为 RGB:

  • RGB = (1.47450, -178.21694, 345.59392)

不幸的是,该 RGB 值存在一些问题:

  • 您的显示器无法显示绿色 (-178.21694);这意味着它是显示器可以显示的颜色之外的颜色。
  • 您的显示器不能显示多于 255 (345.59392) 的蓝色;显示器只和蓝色一样蓝色 - 它不能变得更蓝。这意味着它是显示器可以显示的颜色之外的颜色。

所以我们必须四舍五入:

  • XYZ: (0.342957, 0.106256, 1.900700)
  • xyz: (0.145945, 0.045217, 0.808838)
  • xyY: (0.145945, 0.045217, 0.045217)
  • 实验室: (38.94259, 119.14058, -146.08508) (d65)
  • RGB: (1, 0, 255) (sRGB)

现在我们有了波长 455 nm 光的最接近 sRGB:

在此处输入图片说明


And*_*rey 10

部分"可见波长的近似RGB值"

图片来源:Dan Bruton - 色彩科学

原始FORTRAN代码@(http://www.physics.sfasu.edu/astro/color/spectra.html)

将返回平滑(连续)光谱,在红色侧重.

w - 波长,R,G和B - 颜色成分

忽略伽玛和强度简单的叶子:

if w >= 380 and w < 440:
    R = -(w - 440.) / (440. - 380.)
    G = 0.0
    B = 1.0
elif w >= 440 and w < 490:
    R = 0.0
    G = (w - 440.) / (490. - 440.)
    B = 1.0
elif w >= 490 and w < 510:
    R = 0.0
    G = 1.0
    B = -(w - 510.) / (510. - 490.)
elif w >= 510 and w < 580:
    R = (w - 510.) / (580. - 510.)
    G = 1.0
    B = 0.0
elif w >= 580 and w < 645:
    R = 1.0
    G = -(w - 645.) / (645. - 580.)
    B = 0.0
elif w >= 645 and w <= 780:
    R = 1.0
    G = 0.0
    B = 0.0
else:
    R = 0.0
    G = 0.0
    B = 0.0
Run Code Online (Sandbox Code Playgroud)


msw*_*msw 8

频率与所谓的Hue之间存在关系,但出于复杂的感知原因,监视色域和校准,您可以在昂贵的实验室设备之外实现最佳效果.

请参阅http://en.wikipedia.org/wiki/HSL_and_HSV了解数学,并注意您必须为Hue⇔频率映射提出最佳猜测.我希望这种经验映射不是线性的.

  • 请注意我使用"经验"这个词然后自己尝试,同时记住我们的感知是三色和明显非线性的,并且监视器是不同的三色并且也非常非线性.围绕这些效应建立了整个校准行业. (7认同)

Jer*_*fin 5

这是颜色配置文件处理的大部分内容。基本上,对于给定的设备(扫描仪、相机、显示器、打印机等),颜色配置文件表明一组特定输入将产生哪些实际颜色的光。

另请注意,对于大多数真实设备,您只处理几个离散波长的光,并且中间色不是通过直接产生该波长产生的,而是通过混合不同数量的两个相邻可用波长来产生的。鉴于我们以相同的方式感知颜色,这并不是真正的问题,但取决于您为什么关心,无论如何可能值得了解。

如果没有颜色配置文件(或等效信息),您将缺少将 RGB 值映射到颜色所需的信息。纯红色的 RGB 值通常会映射到设备能够产生/感知的最红的颜色(同样,纯蓝色到最蓝的颜色等)——但最红或最蓝的颜色可以并且会根据(广泛)变化在设备上(在某些情况下不仅仅是设备本身——例如,在打印机中切换墨水可以改变特性)。


小智 5

我认为答案未能解决实际问题的问题.

RGB值通常从XYZ颜色空间导出,该颜色空间是标准人类观察者函数,照明和样品在~360-830范围内的每个波长的相对功率的组合.

我不确定你在这里想要达到的目的,但是可以为样本计算一个相对"准确"的RGB值,其中每个离散频带(例如10nm)完全饱和.变换看起来像这个频谱->XYZ->RGB.查看Bruce Lindbloom的数学网站.从XYZ您也可以轻松计算hue,chroma或者colorimetricL*a*b*.


小智 5

如果你想要精确匹配,那么唯一的解决方案就是用你的光谱值对x,y,z颜色匹配函数进行卷积,这样你最终得到一个(设备无关的)XYZ颜色表示,你可以在以后转换成(设备)相关的)RGB.

这在这里描述:http: //www.cs.rit.edu/~ncs/color/t_spectr.html

你可以在这里找到卷积的x,y,z颜色匹配函数:http: //cvrl.ioo.ucl.ac.uk/cmfs.htm