【发布时间】:2014-03-25 12:38:36
【问题描述】:
我正在尝试将星星的 B-V color index 转换为明显的 RGB 颜色。除了查找表格和色带之外,似乎没有众所周知的算法可以做到这一点。
什么是 B-V 颜色索引?
这是天文学家分配给恒星的数字,以表明其外观颜色。热星(低 B-V)是蓝色/紫色,冷星(高 B-V)是红色,中间有白色/橙色星。
初始算法
B-V 到开尔文
var t = 4600 * ((1 / ((0.92 * bv) + 1.7)) +(1 / ((0.92 * bv) + 0.62)) );
开尔文到 xyY
如果将恒星建模为黑体,则可以使用Planckian locus 的数值近似值来计算 xy 坐标(CIE 色度)
// t to xyY
var x, y = 0;
if (t>=1667 && t<=4000) {
x = ((-0.2661239 * Math.pow(10,9)) / Math.pow(t,3)) + ((-0.2343580 * Math.pow(10,6)) / Math.pow(t,2)) + ((0.8776956 * Math.pow(10,3)) / t) + 0.179910;
} else if (t > 4000 && t <= 25000) {
x = ((-3.0258469 * Math.pow(10,9)) / Math.pow(t,3)) + ((2.1070379 * Math.pow(10,6)) / Math.pow(t,2)) + ((0.2226347 * Math.pow(10,3)) / t) + 0.240390;
}
if (t >= 1667 && t <= 2222) {
y = -1.1063814 * Math.pow(x,3) - 1.34811020 * Math.pow(x,2) + 2.18555832 * x - 0.20219683;
} else if (t > 2222 && t <= 4000) {
y = -0.9549476 * Math.pow(x,3) - 1.37418593 * Math.pow(x,2) + 2.09137015 * x - 0.16748867;
} else if (t > 4000 && t <= 25000) {
y = 3.0817580 * Math.pow(x,3) - 5.87338670 * Math.pow(x,2) + 3.75112997 * x - 0.37001483;
}
xyY to XYZ (Y = 1)
// xyY to XYZ, Y = 1
var Y = (y == 0)? 0 : 1;
var X = (y == 0)? 0 : (x * Y) / y;
var Z = (y == 0)? 0 : ((1 - x - y) * Y) / y;
XYZ to RGB
var r = 0.41847 * X - 0.15866 * Y - 0.082835 * Z;
var g = -0.091169 * X + 0.25243 * Y + 0.015708 * Z;
var b = 0.00092090 * X - 0.0025498 * Y + 0.17860 * Z;
问题
我使用 B-V 颜色索引运行此算法:1.2、1.0、0.59、0.0、-0.29。这就是我得到的输出。
为什么我会得到这个奇怪的输出?热星是蓝色的,冷星是棕色的,而且似乎没有白色/橙色的中间星。
更新
根据Ozan 的评论,我似乎使用了错误的矩阵将 XYZ 转换为 RGB。由于 sRGB 是网络上的默认色彩空间(或者是吗?),我现在使用正确的矩阵,然后使用伽马校正函数 (a = 0.055)。
我现在得到了这个漂亮的颜色渐变,
但四肢仍然没有红色/紫色。
演示
现在您还可以使用fiddle。
更新 2
如果使用 0.5 的 gamma 并将 B-V 颜色指数的范围从 4.7 扩展到 -0.5,我会在一个极端处得到红色,但仍然没有紫色。这是更新后的fiddle。
【问题讨论】:
-
生成的 rgb 值是介于 0 和 1 之间还是 0 和 255 之间?
-
0和1,我乘以255得到输出图像
-
您的 kelvinToXyY 似乎是正确的,我得到 0.476,y: 0.414 为 2500K。我认为你的 XYZ 到 RGB 使用了错误的矩阵,我在 cs.rit.edu/~ncs/color/… 找到了另一个矩阵,试试看
-
@melhosseiny 在我的回答末尾添加了一些与颜色视觉校正相关的链接