Отображать температуру в цвете с C#?
Кто-то знает алгоритм, который получает температуру в градусах Кельвина / Цельсия и возвращает RGB?
Как в тепловизорах.
Я нашел несколько ссылок:
http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_T.html
http://www.fourmilab.ch/documents/specrend/specrend.c
Но я не могу понять, что цвет XYZ?
У меня только температура в градусах Цельсия..
Я могу преобразовать его в любую температуру Формулы преобразования температуры
ОБНОВЛЕНИЕ: файл данных о цвете черного тела Я нашел это... но эти градусы Кельвина невозможны... я имею в виду, что красный цвет должен быть горячим... так почему 8000k это синий, а 1000k это красный...
5 ответов
Лучший вариант - использовать изображение с 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
};
Я понимаю, что это двухлетняя нить, но у меня было то же затруднительное положение.
Я взял данные из таблицы цветов и применил кусочную полиномиальную аппроксимацию 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);
}
Если вы правы, вы ищете теоретический фон по цветовому пространству XYZ
Цветовая температура основана на фактическом цвете света, излучаемого чем-то (теоретически, "идеальным черным телом"), который излучает свет, основываясь исключительно на его температуре.
Некоторые примеры этого вида источника света: если у вас есть элемент электрической плиты, который светится красным, он может быть около 1000K. Обычная нить накаливания составляет около 2700K, а солнце - около 5700K. Все три являются справедливым приближением к "черному телу"; они излучают определенный спектр света в зависимости от их фактической температуры.
Многие искусственные источники света на самом деле не являются "температурой" света, который они излучают (и их спектры, как правило, тоже не являются спектрами черного тела...). Вместо этого, их "температурный" рейтинг - это температура, которой должно быть теоретическое черное тело, чтобы излучать свет этого цвета. Есть также цвета, которые не могут быть созданы черным телом: свет, который зеленоватый или пурпурный по сравнению с более "естественным" на вид освещением черного тела.
Как упомянуто в одном из комментариев, все виды тепловизионных камер, о которых вы, вероятно, думаете, ложные. На дисплее с ложными цветами цвета выбираются только для удобства: для тепловой камеры они могут выбрать "горячий"- красный для теплых и "холодный"- синий для холодных. Но они могут так же легко выбрать диапазон от черного до белого или от фуксии до зеленого.
Поскольку отображение ложных цветов является произвольным, вам действительно нужно проверить цветовую клавишу для определенного изображения или системы, если вы хотите оценить температуру (научные изображения обычно должны иметь какую-то цветовую клавишу для этой цели). Если у вас нет цветового ключа и нет документации о том, как было сгенерировано изображение, вам не повезло.
Вышеуказанная функция переоценивает красный цвет, когда температура> 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 К. Здесь принимаются полиномы высокого порядка, поэтому красный и зеленый должны оставаться постоянными при температуре> 40000 К, в противном случае могут произойти странные вещи.