Отображать температуру как цвет с С#?

Кто-нибудь знает алгоритм, который получает температуру в Kelvin/Celsius и возвращает RGB?

Как в тепловых камерах.

Я нашел несколько ссылок:

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

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

enter image description here

Но я не могу определить, что такое цвет XYZ?

enter image description here

У меня температура только в градусах Цельсия.

Я могу преобразовать его в любую температуру Формулы преобразования температуры

UPDATE: Blackbody Color Datafile Я нашел это... но эти градусы Кельвина невозможны. Я имею в виду красный предположительно, чтобы быть горячим.. так почему 8000k синий, а 1000k красный...

Ответ 1

Лучшим вариантом является использование изображения с GetPixel:

Temperature Gradient

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
    };

Ответ 3

Я понимаю, что это двухлетняя старая нить, но у меня было такое же затруднительное положение.

Я взял данные из таблицы цветов и применил кусочно-полиномиальный 5-й порядок, используя Numpy.polyfit в Python. Из этих коэффициентов я смог придумать функцию С# ниже. Значения 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);
}

Ответ 4

Цветовая температура основана на фактическом цвете света, испускаемого чем-то (теоретически, "идеальном черном теле" ), который испускает свет, основанный исключительно по его температуре.

Некоторые примеры такого рода источников света: если у вас есть электрический элемент печи, который светится красным, это может быть около 1000K. Обычная лампа накаливания накаливания составляет около 2700K, а солнце составляет примерно 5700K. Все три являются справедливыми приближениями "черного тела"; они излучают определенный спектр света, исходя из их фактической температуры.

Многие искусственные источники света на самом деле не являются "температурой" испускаемого ими света (и их спектры, как правило, не являются спектрами черного тела, либо...). Вместо этого их "температура" - это температура, которую теоретическое черное тело должно было бы использовать, чтобы излучать свет этого цвета. Есть также цвета, которые не могут быть созданы черным телом: свет, который является зеленоватым или пурпурным, по сравнению с более "естественным" освещением черного тела.

Как уже упоминалось в одном из комментариев, вид тепловизионных камер, о которых вы, вероятно, думаете, все это ложный цвет. На ложно-цветном дисплее цвета выбираются только для удобства: так что для тепловой камеры они могут выбрать "горячий" красный цвет для теплого и "холодного" синего цвета для холода. Но они могли так же легко выбрать диапазон от черного до белого, или fuschia до зеленого.

Поскольку изображения с ложным цветом являются произвольными, вам действительно нужно проверить цветную клавишу на конкретном изображении или системе, если вы хотите оценить температуру (для научных целей в общем случае для этой цели обычно должен быть какой-то цветовой ключ). Если у вас нет цветового ключа и нет документации о том, как было создано изображение, вам не повезло.

Ответ 5

Вышеуказанная функция переоценивает красный цвет при темпе > 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 +...

Извините, я не знаком с С#, но вы можете легко прочитать коды.

Ошибка для большинства случаев составляет всего 0,5% и не более 1,2% для красного в temp = 6600 K. Полиномы высокого порядка принимаются здесь, поэтому красный и зеленый цвета должны оставаться постоянными при температуре > 40000 К, в противном случае происходят странные вещи.