我需要一个算法或函数的光谱的可见光范围内的各波长映射到它的等效RGB值。 是否有一个光的RGB系统和波长之间的结构关系? 这样的形象: 替代文字http://www1.appstate.edu/~kms/classes/psy3203/Color/spectrum5.gif 对不起,如果这是无关紧要的: - ]
Answer 1:
有频率和所谓的色调之间的关系,但对于感知,显示器色域,和校准复杂的原因,就可以实现的昂贵的实验室设备外,最好是粗略估计。
见http://en.wikipedia.org/wiki/HSL_and_HSV的数学,并注意你必须拿出的色调⇔频率映射你的最好的猜测。 我希望这个经验映射是什么,但线性的。
Answer 2:
我最近发现,因为它们是基于非线性和移位的数据我光谱颜色不正常工作。 所以我做了一点研究和数据汇编,并发现大多数频谱图像在那里是不正确的。 此外,色彩范围不匹配给对方,所以我从这点只用线性化的真实光谱数据这样
这里是我的整流输出:
- 第一频谱是最好的呈现频谱我发现,但仍然遥远动真格
- 第二个是我们的太阳的线性光谱从地球上拍摄
- 最后一个是我目前的彩色输出
下面是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); }
}
//--------------------------------------------------------------------------
哪里
-
l
是在波长[nm]的可用valueas是l = < 400.0 , 700.0 >
-
r,g,b
正在返回的颜色分量在范围< 0.0 , 1.0 >
Answer 3:
部分“为可见光波长近似RGB值”
信用:丹布鲁顿 - 色彩科技
原始FORTRAN代码@( http://www.physics.sfasu.edu/astro/color/spectra.html )
将返回在红方平滑(连续)频谱,沉重。
瓦特 - 波长,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
Answer 4:
我认为答案未能解决问题的实际问题。
RGB值通常从XYZ色空间是一个标准的人类观察者功能,照射和样品在每一个波长上〜360-830范围内的相对功率的组合导出。
我不知道你正试图在这里实现什么,但它是可以计算的样本在频谱@的每个离散频段说10nm的是完全饱和的相对“准确”的RGB值。 变换这个样子的频谱->XYZ->RGB
。 看看布鲁斯Lindbloom的站点为数学。 从XYZ还可以容易地计算出hue
, chroma
或colorimetric
值,例如L*a*b*
。
Answer 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
Answer 6:
这是最有什么型材颜色处理。 基本上,对于给定的设备(扫描仪,照相机,监视器,打印机等)的颜色配置文件讲述什么光的实际颜色将通过一组特定的输入来产生。
还要注意,对于大多数实际设备,则仅处理光的几个离散波长,和中间的颜色产生不通过直接产生该波长,但是通过混合不同量的可用的相邻的两个波长。 鉴于我们以同样的方式感知颜色,这不是一个真正的问题,但是这取决于你为什么关心,它可能是值得了解的反正。
没有颜色配置文件(或同等信息)你缺乏必要的映射RGB值的色彩信息。 纯红色的RGB值通常将映射到该设备能够产生/感测的(并且同样地,纯蓝色到最蓝的颜色)最红的颜色 - 但是,“最红”或“蓝的”可以并且将改变(广泛)基于在装置上。
Answer 7:
的波长转换为RGB色彩
首先您咨询CIE 1964补充标准色度观测图( 存档 )
https://imgur.com/a/JDatZNm
查查CIE颜色匹配函数值你想要的波长。
例如,我想455纳米的光的颜色:
对于我们所期望的波长:
| 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 |
注:色度坐标简单地从CIE颜色匹配函数来计算:
x = X / (X+Y+Z)
y = Y / (X+Y+Z)
z = Z / (Z+Y+Z)
鉴于:
X+Y+Z = 0.342257+0.106256+1.90070 = 2.349913
我们计算:
x = 0.342257 / 2.349913 = 0.145945
y = 0.106256 / 2.349913 = 0.045217
z = 1.900700 / 2.349913 = 0.808838
您可以使用两种不同的色彩空间中指定的455纳米的光:
- 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
我们现在有3个不同的色彩空间中指定的455纳米的光:
- 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?
XYZ,XYZ和xyY表是绝对的色彩空间描述使用绝对物理颜色。
同时,每一个实际的色彩空间,人们使用:
- 实验室
- LUV
- HSV
- HSL
- RGB
取决于一些白点 。 然后,将颜色被描述为相对于该白点。
例如,
- RGB白色(255,255,255)的意思是“白色”
- 实验室白色(100,0,0)表示“白”
- LCH白色(100,0,309)的意思是“白色”
- HSL白色(240,0,100)的意思是“白色”
- HSV白色(240,0,100)的意思是“白色”
但是,有没有这样的颜色为白色。 你如何定义白? 阳光的颜色?
- 在一天中什么时间?
- 有多少云?
- 在什么范围?
- 在地球上?
有些人用他们的(可怕的橙色)白炽灯泡的白是指白色。 有些人用他们的荧光灯灯光的颜色。 有白没有绝对的物理定义 - 白了就是在我们的大脑。
因此,我们必须选择一个白色
我们一定要选白色。 (真的, 你必须选择一个白色),并有大量白色可供选择:
- 光源A :有点像钨灯
- 光源B&C :通过把过滤器钨灯的前面试图伪装正午日光
- 光源D50 :5000K自然光
- 光源D55 :5500K自然光
- D65光源 :6504K自然光
- 光源D75 :7500K自然光
- 光源è :理论同样存在的所有颜色的
- 光源˚F :荧光灯 (FL8)
- 光源大号 :LED照明
我会挑选一个白色的为您服务。 该sRGB的使用相同的白色:
- D65 -北欧晴朗夏日的日光照明
D65(其中有一个颜色接近6504K,但地球大气的不完全是因为),有一个颜色:
- XYZ_D65:(0.95047,1.00000,1.08883)
就这样,您可以将转换XYZ
到Lab
(或Luv
) -色彩空间同样能够表达所有的理论色彩。 现在我们有445纳米的光的单色发射的第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:
- 不仅是相对于一些白点颜色
- 红,绿,蓝:但是相对于三原色也
如果指定的(255,0,0),你说你要“正当红的” RGB颜色。 但没有红色的定义。 有“红”,“绿”或“蓝”没有这样的事。 彩虹是连续的,并且不带箭头的说法:
这是红
又一次,这意味着我们要挑三挑三个基色。 你必须选择你的三原色说什么“红色”,“绿色”和“蓝色”是。 并再次你有红,绿,蓝的许多不同defintions可供选择:
- CIE 1931
- ROMM RGB
- 的Adobe色域广RGB
- DCI-P3
- NTSC(1953)
- 苹果RGB
- 的sRGB
- 日本NTSC
- PAL / SECAM
- Adobe RGB的98
- scRGB
我来接你。 我会挑这三种颜色:
- 红色 :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纳米的最接近的sRGB:
Answer 8:
Patapom有它差不多吧:每个波长你计算CIE XYZ值,然后将其转换那些使用标准公式(说)的sRGB(如果你幸运的话,你会发现代码,你可以只使用要做到这一点的转换)。 因此,关键的一步是获得XYZ值。 幸运的是,对于单波长的光,这是容易:XYZ色彩匹配函数是简单地列出的XYZ值对于给定波长的表。 因此,只要看看它。 如果你有光更复杂的频谱,也许一个黑色的机身,那么你不得不倍光每个波长的平均量的XYZ响应。
Answer 9:
VBA代码是从由Dan布鲁顿(astro@tamu.edu)近似“为可见波长RGB值”的。 链接到他原来的Fortran代码: http://www.physics.sfasu.edu/astro/color/spectra.html光谱方案: http://www.efg2.com/Lab/ScienceAndEngineering/Spectra.htm
Sub Wavelength_To_RGB()
'Purpose: Loop thru the wavelengths in the visible spectrum of light
' and output the RGB values and colors to a worksheet.
' Wavelength range: 380nm and 780nm
Dim j As Long, CellRow As Long
Dim R As Double, G As Double, B As Double
Dim iR As Integer, iG As Integer, iB As Integer
Dim WL As Double
Dim Gamma As Double
Dim SSS As Double
Gamma = 0.8
CellRow = 1
For j = 380 To 780
WL = j
Select Case WL
Case 380 To 440
R = -(WL - 440#) / (440# - 380#)
G = 0#
B = 1#
Case 440 To 490
R = 0#
G = ((WL - 440#) / (490# - 440#))
B = 1#
Case 490 To 510
R = 0#
G = 1#
B = (-(WL - 510#) / (510# - 490#))
Case 510 To 580
R = ((WL - 510#) / (580# - 510#))
G = 1#
B = 0#
Case 580 To 645
R = 1#
G = (-(WL - 645#) / (645# - 580#))
B = 0#
Case 645 To 780
R = 1#
G = 0#
B = 0#
Case Else
R = 0#
G = 0#
B = 0#
End Select
'LET THE INTENSITY SSS FALL OFF NEAR THE VISION LIMITS
If WL > 700 Then
SSS = 0.3 + 0.7 * (780# - WL) / (780# - 700#)
ElseIf WL < 420 Then
SSS = 0.3 + 0.7 * (WL - 380#) / (420# - 380#)
Else
SSS = 1#
End If
'GAMMA ADJUST
R = (SSS * R) ^ Gamma
G = (SSS * G) ^ Gamma
B = (SSS * B) ^ Gamma
'Multiply by 255
R = R * 255
G = G * 255
B = B * 255
'Change RGB data type from Double to Integer.
iR = CInt(R)
iG = CInt(G)
iB = CInt(B)
'Output to worksheet
Cells(CellRow, 1).Interior.Color = RGB(iR, iG, iB)
Cells(CellRow, 2) = WL
Cells(CellRow, 3) = "(" & iR & "," & iG & "," & iB & ")"
CellRow = CellRow + 1
Next j
End Sub