14

有人知道以开尔文/摄氏度获取温度并返回 RGB 的算法吗?

就像在热像仪中一样。

我找到了一些链接:

http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_T.html

http://www.fourmilab.ch/documents/specrend/specrend.c

在此处输入图像描述

但我不知道 XYZ 颜色是什么?

在此处输入图像描述

我只有摄氏温度..

我可以将其转换为任何温度温度转换公式

更新: 黑体颜色数据文件 我找到了这个..但是那些开尔文度是不可能的..我的意思是红色假设很热..那么为什么 8000k 是蓝色而 1000k 是红色......

4

5 回答 5

9

最好的选择是使用带有GetPixel的图像:

温度梯度

private void UpdateTemp()
{
    Bitmap temps = (Bitmap)Properties.Resources.temp;
    if (curTemp >= 0)
    {
        int i = curTemp;
        if (i < 0)
            i = 0;
        if (i > temps.Width-1)
            i = temps.Width-1;
        this.BackColor = temps.GetPixel(i, 10);
    }
}

或者构建一个数组。资源

    private static Color[] colors = 
    {
        Color.FromArgb(155, 188, 255), //    40000
        Color.FromArgb(155, 188, 255), //    39500
        Color.FromArgb(155, 188, 255), //    39000
        Color.FromArgb(155, 188, 255), //    38500
        Color.FromArgb(156, 188, 255), //    38000
        Color.FromArgb(156, 188, 255), //    37500
        Color.FromArgb(156, 189, 255), //    37000
        Color.FromArgb(156, 189, 255), //    36500
        Color.FromArgb(156, 189, 255), //    36000
        Color.FromArgb(157, 189, 255), //    35500
        Color.FromArgb(157, 189, 255), //    35000
        Color.FromArgb(157, 189, 255), //    34500
        Color.FromArgb(157, 189, 255), //    34000
        Color.FromArgb(157, 189, 255), //    33500
        Color.FromArgb(158, 190, 255), //    33000
        Color.FromArgb(158, 190, 255), //    32500
        Color.FromArgb(158, 190, 255), //    32000
        Color.FromArgb(158, 190, 255), //    31500
        Color.FromArgb(159, 190, 255), //    31000
        Color.FromArgb(159, 190, 255), //    30500
        Color.FromArgb(159, 191, 255), //    30000
        Color.FromArgb(159, 191, 255), //    29500
        Color.FromArgb(160, 191, 255), //    29000
        Color.FromArgb(160, 191, 255), //    28500
        Color.FromArgb(160, 191, 255), //    28000
        Color.FromArgb(161, 192, 255), //    27500
        Color.FromArgb(161, 192, 255), //    27000
        Color.FromArgb(161, 192, 255), //    26500
        Color.FromArgb(162, 192, 255), //    26000
        Color.FromArgb(162, 193, 255), //    25500
        Color.FromArgb(163, 193, 255), //    25000
        Color.FromArgb(163, 193, 255), //    24500
        Color.FromArgb(163, 194, 255), //    24000
        Color.FromArgb(164, 194, 255), //    23500
        Color.FromArgb(164, 194, 255), //    23000
        Color.FromArgb(165, 195, 255), //    22500
        Color.FromArgb(166, 195, 255), //    22000
        Color.FromArgb(166, 195, 255), //    21500
        Color.FromArgb(167, 196, 255), //    21000
        Color.FromArgb(168, 196, 255), //    20500
        Color.FromArgb(168, 197, 255), //    20000
        Color.FromArgb(169, 197, 255), //    19500
        Color.FromArgb(170, 198, 255), //    19000
        Color.FromArgb(171, 198, 255), //    18500
        Color.FromArgb(172, 199, 255), //    18000
        Color.FromArgb(173, 200, 255), //    17500
        Color.FromArgb(174, 200, 255), //    17000
        Color.FromArgb(175, 201, 255), //    16500
        Color.FromArgb(176, 202, 255), //    16000
        Color.FromArgb(177, 203, 255), //    15500
        Color.FromArgb(179, 204, 255), //    15000
        Color.FromArgb(180, 205, 255), //    14500
        Color.FromArgb(182, 206, 255), //    14000
        Color.FromArgb(184, 207, 255), //    13500
        Color.FromArgb(186, 208, 255), //    13000
        Color.FromArgb(188, 210, 255), //    12500
        Color.FromArgb(191, 211, 255), //    12000
        Color.FromArgb(193, 213, 255), //    11500
        Color.FromArgb(196, 215, 255), //    11000
        Color.FromArgb(200, 217, 255), //    10500  
        Color.FromArgb(204, 219, 255), //    10000
        Color.FromArgb(208, 222, 255), //    9500
        Color.FromArgb(214, 225, 255), //    9000
        Color.FromArgb(220, 229, 255), //    8500
        Color.FromArgb(227, 233, 255), //    8000
        Color.FromArgb(235, 238, 255), //    7500
        Color.FromArgb(245, 243, 255), //    7000
        Color.FromArgb(255, 249, 253), //    6500
        Color.FromArgb(255, 243, 239), //    6000
        Color.FromArgb(255, 236, 224), //    5500
        Color.FromArgb(255, 228, 206), //    5000
        Color.FromArgb(255, 219, 186), //    4500
        Color.FromArgb(255, 209, 163), //    4000
        Color.FromArgb(255, 196, 137), //    3500
        Color.FromArgb(255, 180, 107), //    3000
        Color.FromArgb(255, 161,  72), //    2500
        Color.FromArgb(255, 137,  18), //    2000
        Color.FromArgb(255, 109,   0), //    1500 
        Color.FromArgb(255,  51,   0), //    1000
    };
于 2011-09-03T16:13:31.960 回答
5

我意识到这是一个两年前的话题,但我也遇到了同样的困境。

我从颜色表中获取数据,并在 Python 中使用 Numpy.polyfit 应用了分段 5 阶多项式拟合。从这些系数中,我能够想出下面的 C# 函数。拟合的 R 平方值接近或超过 0.999。它在其大部分领域的误差小于 0.01%,但确实有几个点接近 3%。不过,对于大多数情况应该足够好。

private Color blackBodyColor(double temp)
{
    float x = (float)(temp / 1000.0);
    float x2 = x * x;
    float x3 = x2 * x;
    float x4 = x3 * x;
    float x5 = x4 * x;

    float R, G, B = 0f;

    // red
    if (temp <= 6600)
        R = 1f;
    else
        R = 0.0002889f * x5 - 0.01258f * x4 + 0.2148f * x3 - 1.776f * x2 + 6.907f * x - 8.723f;

    // green
    if (temp <= 6600)
        G = -4.593e-05f * x5 + 0.001424f * x4 - 0.01489f * x3 + 0.0498f * x2 + 0.1669f * x - 0.1653f;
    else
        G = -1.308e-07f * x5 + 1.745e-05f * x4 - 0.0009116f * x3 + 0.02348f * x2 - 0.3048f * x + 2.159f;

    // blue
    if (temp <= 2000f)
        B = 0f;
    else if (temp < 6600f)
        B = 1.764e-05f * x5 + 0.0003575f * x4 - 0.01554f * x3 + 0.1549f * x2 - 0.3682f * x + 0.2386f;
    else
        B = 1f;

    return Color.FromScRgb(1f, R, G, B);
}
于 2013-11-25T01:43:55.507 回答
3

如果你做对了,你正在寻找关于XYZ 颜色空间的理论背景

于 2011-08-29T12:22:45.630 回答
2

色温基于从仅根据其温度发光的物体(理论上,“理想黑体”)发出的光的实际颜色。

这种光源的一些例子:如果你有一个发红光的电炉元件,它可能在 1000K 左右。普通白炽灯泡灯丝约为 2700K,太阳约为 5700K。这三个都是“黑体”的近似值;它们会根据实际温度发出特定光谱。

许多人造光源实际上并不是它们发出的光的“温度”(它们的光谱通常也不是黑体光谱......)。相反,它们的“温度”等级是理论上黑体必须达到的温度才能发出那种颜色的光。还有一些颜色是黑体无法产生的:与看起来更“自然”的黑体照明相比,光线偏绿或偏紫。

正如其中一条评论中提到的,您可能正在考虑的那种热像仪显示器都是假彩色的。在伪彩色显示器中,选择颜色只是为了方便:因此,对于热像仪,他们可能会选择看起来“热”的红色表示暖色,选择“冷色”的蓝色表示冷。但是,他们可以轻松地选择从黑色到白色或紫红色到绿色的范围。

因为假色显示是任意的,如果你想估计温度,你真的需要检查特定图像或系统的颜色键(为此,科学图像通常应该有某种颜色键)。如果您没有颜色键,也没有关于如何生成图像的文档,那么您就不走运了。

于 2011-08-29T19:54:37.377 回答
0

当温度 > 10000 K 时,上述函数高估红色。当温度 > 14000 时,颜色变为紫色。我用 7 阶多项式重新拟合了数据。的系数应为:

def temp_to_rgb(temp):
    t = temp/1000.

    # calculate red
    if t < 6.527:
        red = 1.0
    else:
        coeffs = [  4.93596077e+00,  -1.29917429e+00,
                    1.64810386e-01,  -1.16449912e-02,
                    4.86540872e-04,  -1.19453511e-05,
                    1.59255189e-07,  -8.89357601e-10]
        tt = min(t,40)
        red = poly(coeffs,tt)
    red = max(red,0)
    red = min(red,1)

    # calcuate green
    if t < 0.85:
        green = 0.0
    elif t < 6.6:
        coeffs = [ -4.95931720e-01,   1.08442658e+00,
                   -9.17444217e-01,   4.94501179e-01,
                   -1.48487675e-01,   2.49910386e-02,
                   -2.21528530e-03,   8.06118266e-05]
        green = poly(coeffs,t)
    else:
        coeffs = [  3.06119745e+00,  -6.76337896e-01,
                    8.28276286e-02,  -5.72828699e-03,
                    2.35931130e-04,  -5.73391101e-06,
                    7.58711054e-08,  -4.21266737e-10]
        tt = min(t,40)
        green = poly(coeffs,tt)
    green = max(green,0)
    green = min(green,1)

    # calculate blue
    if t < 1.9:
        blue = 0.0
    elif t < 6.6:
        coeffs = [  4.93997706e-01,  -8.59349314e-01,
                    5.45514949e-01,  -1.81694167e-01,
                    4.16704799e-02,  -6.01602324e-03,
                    4.80731598e-04,  -1.61366693e-05]
        blue = poly(coeffs,t)
    else:
        blue = 1.0
    blue = max(blue,0)
    blue = min(blue,1)

    return (red,green,blue)

这里 poly(coeffs,x) = coeffs[0] + coeffs[1]*x + coeffs[2]*x**2 + ...

抱歉,我不熟悉 C#,但您可以轻松阅读代码。

大多数情况下误差在 0.5% 以内,红色在 temp = 6600 K 时最多误差在 1.2% 以内。这里采用高阶多项式,因此红色和绿色必须在 temp > 40000 K 时保持恒定,否则会发生奇怪的事情。

于 2014-07-21T00:43:29.810 回答