我需要一种算法或函数来将可见光谱范围的每个波长映射到其等效的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 >
Ian*_*oyd 11
首先,您查阅CIE 1964 补充标准色度观察者图表(存档)
并查找所需波长的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 光:
我们还可以添加第三个颜色空间:xyY
x = x = 0.145945
y = y = 0.045217
Y = y = 0.045217
Run Code Online (Sandbox Code Playgroud)
我们现在在 3 个不同的颜色空间中指定了 455 nm 的光:
因此,我们已将纯单色发射光的波长转换为XYZ颜色。现在我们要将其转换为 RGB。
XYZ、xyz和xyY是使用绝对物理描述颜色的绝对颜色空间。
同时,人们使用的每一个实用的色彩空间:
取决于一些白点。然后将颜色描述为相对于该白点。
例如,
但是没有像白色这样的颜色。你如何定义白色?阳光的颜色?
有些人使用他们(可怕的橙色)白炽灯泡的白色来表示白色。有些人使用荧光灯的颜色。白色没有绝对的物理定义——白色存在于我们的大脑中。
我们必须选择白色。(真的你必须选择白色。)还有很多白色可供选择:
我会为你挑选一件白色的。sRGB 使用的相同白色:
D65(它的颜色接近 6504K,但不完全是因为地球的大气层),具有以下颜色:
有了它,您可以将您的转换XYZ
为Lab
(或Luv
) - 一个同样能够表达所有理论颜色的颜色空间。现在我们有了 445 nm 单色光发射的第 4 色空间表示:
Lab
(和Luv
) 是相对于某个白点的颜色空间。即使您被迫选择一个任意的白点,您仍然可以表示每种可能的颜色。
RGB 不是那样的。使用 RGB:
如果您将 RGB 颜色指定为 (255, 0, 0),则表示您想要“只是红色”。但是没有红色的定义。没有“红”、“绿”或“蓝”之类的东西。彩虹是连续的,没有箭头说:
这是红色的
这再次意味着我们必须挑三挑三原色。您必须选择三种原色来说明“红色”、“绿色”和“蓝色”是什么。同样,您有许多不同的红色、绿色、蓝色定义可供选择:
我给你挑。我会选择这三种颜色:
这些也是 1996 年国际委员会选择的初选。
他们创建了一个标准,说每个人都应该使用:
他们称之为标准sRGB
。
现在我们选择了我们的
我们现在可以将您的 XYZ 颜色转换为 RGB:
不幸的是,该 RGB 值存在一些问题:
所以我们必须四舍五入:
现在我们有了波长 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)
频率与所谓的Hue之间存在关系,但出于复杂的感知原因,监视色域和校准,您可以在昂贵的实验室设备之外实现最佳效果.
请参阅http://en.wikipedia.org/wiki/HSL_and_HSV了解数学,并注意您必须为Hue⇔频率映射提出最佳猜测.我希望这种经验映射不是线性的.
这是颜色配置文件处理的大部分内容。基本上,对于给定的设备(扫描仪、相机、显示器、打印机等),颜色配置文件表明一组特定输入将产生哪些实际颜色的光。
另请注意,对于大多数真实设备,您只处理几个离散波长的光,并且中间色不是通过直接产生该波长产生的,而是通过混合不同数量的两个相邻可用波长来产生的。鉴于我们以相同的方式感知颜色,这并不是真正的问题,但取决于您为什么关心,无论如何可能值得了解。
如果没有颜色配置文件(或等效信息),您将缺少将 RGB 值映射到颜色所需的信息。纯红色的 RGB 值通常会映射到设备能够产生/感知的最红的颜色(同样,纯蓝色到最蓝的颜色等)——但最红或最蓝的颜色可以并且会根据(广泛)变化在设备上(在某些情况下不仅仅是设备本身——例如,在打印机中切换墨水可以改变特性)。
小智 5
我认为答案未能解决实际问题的问题.
RGB值通常从XYZ颜色空间导出,该颜色空间是标准人类观察者函数,照明和样品在~360-830范围内的每个波长的相对功率的组合.
我不确定你在这里想要达到的目的,但是可以为样本计算一个相对"准确"的RGB值,其中每个离散频带(例如10nm)完全饱和.变换看起来像这个频谱->XYZ->RGB
.查看Bruce Lindbloom的数学网站.从XYZ您也可以轻松计算hue
,chroma
或者colorimetric
像L*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