Отображать температуру в цвете с C #? - PullRequest
13 голосов
/ 29 августа 2011

Кто-то знает алгоритм, который получает температуру в градусах Кельвина / Цельсия и возвращает 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

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

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

ОБНОВЛЕНИЕ: Файл данных цвета черного тела Я нашел это ... но эти градусы Кельвина невозможны ... я имею в виду, что красный цвет должен быть горячим ... так почему 8000k это синий, а 1000k это красный ...

Ответы [ 5 ]

8 голосов
/ 03 сентября 2011

Лучшим вариантом является использование изображения с 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
    };
4 голосов
/ 25 ноября 2013

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

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

Если вы правильно поняли, вы ищете теоретический фон для XYZ цветового пространства

2 голосов
/ 29 августа 2011

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

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

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

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

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

0 голосов
/ 21 июля 2014

Вышеуказанная функция переоценивает красный цвет, когда температура> 10000 К. Цвета становятся фиолетовыми, когда температура> 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%, а для красного - не более 1,2% при темп. = 6600 K. Высокий порядокздесь приняты полиномы, поэтому красный и зеленый должны оставаться постоянными при температуре> 40000 К. В противном случае могут произойти странные вещи.

...