2011-08-29 123 views
12

有人知道一個算法獲得溫度以開爾文/攝氏度並返回RGB?用C#顯示顏色的顏色?

就像熱成像相機。

我發現了一些鏈接:

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

我只有攝氏溫度..

我可以將其轉換爲任何溫度Temperature Conversion Formulas

UPDATE: Blackbody Color Datafile 我發現這個..但那些開度是不可能的..我的意思是 紅色假設是熱的..所以爲什麼8000k是藍色和1000k是紅色的......

+6

第二個鏈接包含完整的實現。閱讀代碼應該是所有必要的。 –

+2

請原諒我的無知:但是,溫度不是一個單一的值,可以直接映射到一個簡單的預先定義的梯度單點? – Bobby

+0

@Bobby多數民衆贊成我正在努力做什麼.. 但我在哪裏可以得到ot我怎麼能做一個預先定義的漸變? – Danpe

回答

8

最好的辦法是用圖片與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); 
    } 
} 

或是建一個數組。 Source

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

Color temperature是基於光的實際顏色從東西(理論上,「理想黑體」)發出的僅發出基於光其溫度

這種光源的一些例子:如果你有一個發紅光的電爐元件,它可能在1000K左右。普通的白熾燈泡燈絲大約2700K,太陽大約5700K。這三者都是「黑體」的合理近似值;他們根據實際溫度發出特定光譜。

許多人造光源實際上並不是它們發出的光的「溫度」(並且它們的光譜通常不是黑體光譜,或者......)。相反,它們的「溫度」等級是理論黑體必須爲了發射顏色顏色的溫度。也有不能由黑體產生的顏色:與更「自然」的黑體照明相比,呈綠色或略帶紫色的光。

正如其中一條評論所述,您可能想到的那種熱像儀顯示器都是假色。在假彩色顯示屏中,顏色只是爲了方便而選擇的:因此,對於熱成像攝像機,他們可能會選擇「熱」紅色表示溫暖,而「冷」藍色表示冷。但是,他們可以輕鬆選擇從黑色到白色,或從紫紅到綠色的範圍。因爲假彩色顯示是任意的,所以如果你想估計溫度(科學圖像通常應該具有某種顏色鍵),你確實需要檢查特定圖像或系統的顏色鍵。如果您沒有彩色鍵,並且沒有關於如何生成圖像的文檔,那麼您運氣不好。

3

我意識到這是一個爲期兩年的舊線,但我有同樣的困境。

我從顏色表中獲取數據,並使用Python中的Numpy.polyfit應用了分段5階多項式擬合。從這些係數中我可以得到下面的C#函數。擬合的R平方值接近或超過0.999。它的大部分域的誤差都小於.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); 
} 
+0

您可以改用Color.FromArgb嗎?顯然從ScRgb到Argb的映射不是線性的:http://stackoverflow.com/questions/13096933/fromargb-vs-fromscrgb –

0

當temp> 10000 K時,上述函數高估紅色。當temp> 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) 

這裏的聚(coeffs中,x)= coeffs [0] + coeffs [1] * X + coeffs [2] * X ** 2 + ...

對不起,我不熟悉C#,但可以輕鬆閱讀代碼。

對於大多數情況,誤差在0.5%以內,在溫度爲6600 K時紅色誤差在1.2%以下。這裏採用高階多項式,所以紅色和綠色在溫度> 40000 K時必須保持不變,否則奇怪的事情會發生。

+0

對不起,對於R,G,B,6500K不是最大值(1,1,1) 。它結束(1,0.955,0.985)。如果您有足夠的時間進行適當的調整,將每個最大值設置爲一個很好的功能。如果有人對此感興趣,我已將您的僞代碼轉換爲C#。 –