2012-12-20 12 views
22

Napisałem lib do pracy z kolorami i utknąłem próbując obliczyć Tc(k). Z tego, co przeczytałem, praca w przestrzeni barwnej CIE 1931 jest drogą do zrobienia i można ją uzyskać za pomocą xyY.Oblicz temperaturę kolorów w K

Do tej pory mam wszystko poprawne do punktu zastanawianie się poprawną x i y od:

  X     Y 
x = ____________ y = ____________ 
    (X + Y + Z)  (X + Y + Z) 

Liczby wiele do wykresu, ale nie mogę znaleźć nic ze szczegółami dotyczącymi jak idziesz z x i y do Tc(K)

enter image description here

np: dla # FF0000 otrzymuję następujący.

x: 0.64007449945677 
y: 0.32997051063169 

Przeczytałem wiele artykułów na ten temat i za wszelką cenę wszystkie artykuły Wikipedii. Wszystkie pytania, na które natknąłem się w SO, są po prostu powiązane z artykułem wiki o kolorach, nie widziałem takiego, który ma aktualny wzór do obliczania Tc(k)

+1

Możesz wypróbować jedną z tych [przybliżonych wartości temperatury kolorów] (http://en.wikipedia.org/wiki/Color_temperature#Approximation). Po drugie szukacie [locus Planckian] (http://en.wikipedia.org/wiki/Planckian_locus#Approximation). – user7116

+0

Kolor czarnego ciała jest w rzeczywistości spektrum, a nie czystym spektralnym kolorem. Na przykład kolor może być biały, nawet jeśli pik koloru może być zielony. Jakakolwiek formuła musiałaby obejmować ustalenie równoważnego koloru CIE poprzez analizę odpowiedzi prętów i stożków oka. – UncleO

Odpowiedz

1

Zrobiłem trochę kopania w niektórych aplikacjach open source i znalazłem coś w UFRaw. Nie do końca zrozumiałem, co się dzieje.

Znaleźliśmy również paper, który wydaje się dość dobrze omawiać temat.

przeliczona na php i to, co mam tak daleko:

$temp = array(9500, 7000, 5500, 3750, 3000, 2700, 2250, 1800, 1500); 
$hex = array('9DBEFF', 'E4EEFF', 'FFE4BE', 'FFA04C', 'FF7A26', 'FF6A19', 'FF500B', 'FF3403', 'FF2300'); 

echo '<h3>K -> RGB</h3>'; 
foreach ($temp as $k) { 
    $rgb = ColourConverter::temperature2rgb($k); 
    echo sprintf('<div style="background-color:rgb(%s); text-align: center; width: 100px; height: 25px; clear: both;">%s</div>', implode(', ', $rgb), $k); 
} 

echo '<h3>RGB -> K</h3>'; 
foreach ($hex as $v) { 
    $rgb = array_values(ColourConverter::hex2rgb($v)); 
    $k = round(ColourConverter::rgb2temperature($rgb[0], $rgb[1], $rgb[2])); 
    echo sprintf('<div style="background-color:rgb(%s); text-align: center; width: 100px; height: 25px; clear: both;">%s</div>', implode(', ', $rgb), $k); 
} 

Reference

Moja wyjściowa:

output

Całkiem blisko, ale jeszcze nie w 100%. (Znaleziono bug w moim kodu i jest teraz prawie idealny)

  • Kolory są nieco się dzieje z k -> RGB
  • To nie działa w ten k -> RGB -> K. Nie powrócisz do tej samej wartości.

Kod

UFRaw line 246-294

void Temperature_to_RGB(double T, double RGB[3]) 
{ 
    int c; 
    double xD, yD, X, Y, Z, max; 
    // Fit for CIE Daylight illuminant 
    if (T <= 4000) { 
     xD = 0.27475e9/(T * T * T) - 0.98598e6/(T * T) + 1.17444e3/T + 0.145986; 
    } else if (T <= 7000) { 
     xD = -4.6070e9/(T * T * T) + 2.9678e6/(T * T) + 0.09911e3/T + 0.244063; 
    } else { 
     xD = -2.0064e9/(T * T * T) + 1.9018e6/(T * T) + 0.24748e3/T + 0.237040; 
    } 
    yD = -3 * xD * xD + 2.87 * xD - 0.275; 

    // Fit for Blackbody using CIE standard observer function at 2 degrees 
    //xD = -1.8596e9/(T*T*T) + 1.37686e6/(T*T) + 0.360496e3/T + 0.232632; 
    //yD = -2.6046*xD*xD + 2.6106*xD - 0.239156; 

    // Fit for Blackbody using CIE standard observer function at 10 degrees 
    //xD = -1.98883e9/(T*T*T) + 1.45155e6/(T*T) + 0.364774e3/T + 0.231136; 
    //yD = -2.35563*xD*xD + 2.39688*xD - 0.196035; 

    X = xD/yD; 
    Y = 1; 
    Z = (1 - xD - yD)/yD; 
    max = 0; 
    for (c = 0; c < 3; c++) { 
     RGB[c] = X * XYZ_to_RGB[0][c] + Y * XYZ_to_RGB[1][c] + Z * XYZ_to_RGB[2][c]; 
     if (RGB[c] > max) max = RGB[c]; 
    } 
    for (c = 0; c < 3; c++) RGB[c] = RGB[c]/max; 
} 

void RGB_to_Temperature(double RGB[3], double *T, double *Green) 
{ 
    double Tmax, Tmin, testRGB[3]; 
    Tmin = 2000; 
    Tmax = 23000; 
    for (*T = (Tmax + Tmin)/2; Tmax - Tmin > 0.1; *T = (Tmax + Tmin)/2) { 
     Temperature_to_RGB(*T, testRGB); 
     if (testRGB[2]/testRGB[0] > RGB[2]/RGB[0]) 
      Tmax = *T; 
     else 
      Tmin = *T; 
    } 
    *Green = (testRGB[1]/testRGB[0])/(RGB[1]/RGB[0]); 
    if (*Green < 0.2) *Green = 0.2; 
    if (*Green > 2.5) *Green = 2.5; 
} 
+4

Witaj znajomy, Link jest zepsuty, czy możesz zaktualizować tę odpowiedź? – khaintt

1

Jeśli dobrze cię rozumiem, zobacz to pdf, gdzie kilka metod (krótko:() opisano z tego PDF.

[CCT1] Obliczenia są prowadzone z wykorzystaniem CIE 1960 jednolitej przestrzeni kolorów współrzędne u v współrzędne U i V pochodzi od X i Y, przy wykorzystaniu wzorów . U = 4x/(12y-2x + 3) i v = 6y/(12y-2x + 3) Skorelowana temperatura barwowa jest zdefiniowana jako temperatura ciała doskonale czarnego, który leży najbliżej współrzędnych u, v źródła testu. Dwie oddzielne metody dają wyniki iteracyjne oparte na definicji, a drugą jest powszechnie stosowana metoda Robertsona polegająca na interpolacji na podstawie wstępnie obliczonych parametrów u, v i odwrotnego nachylenia. iteracji Jeśli uS i VS są wartościami źródła testowych i uT VT są wartościami blackbody w temperaturze T, skorelowana temperaturze koloru jest wartość T, gdzie:

sqrt((uS - uT)^2 + (vS - vT)^2) 

jest zminimalizowane. Dostosowanie temperatury T w celu uzyskania minimum tej funkcji zostało wykonane przy użyciu arkuszy kalkulacyjnych (Quattro Pro 8 i Excel 97). Oba arkusze kalkulacyjne dawały identyczne wartości.

Nie wiem, czy to naprawdę pomaga.

0

Wikipedii stwierdza, że ​​temperatura barwowa jest obliczana z uwzględnieniem U-V chromaticities, nie x-y, więc trzeba wykonać tłumaczenie. Mimo to zalecam użycie przybliżenia (wyjaśnionego również w Wikipedii) zgodnie z sugestiami @sixlettervariables.

Prawdziwe pytanie brzmi: co próbujesz znaleźć temperaturę koloru? Widzę odniesienie (# FF0000) do kolorów RGB, które są bez znaczenia bez określania przestrzeni kolorów. Przypuśćmy, że jesteś w sRGB (aby ponownie móc point you at Wikipedia), musisz najpierw uzyskać liniowe współrzędne RGB przed przejściem do XYZ.

1

Na podstawie artykułu z Wikipedii wszedłem do przybliżone formuły Color Temperature obliczenia w Excelu jako

=(-449*((R1-0,332)/(S1-0,1858))^3)+(3525*((R1-0,332)/(S1-0,1858))^2)-(6823,3*((R1-0,332)/(S1-0,1858)))+(5520,33)

R1 is color space x coordinate from 0 to 1 
S1 is color space y coordinate from 0 to 1 

działa dobrze!

0

Zdaję sobie sprawę, że jest to stare pytanie, ale ja też starałem się znaleźć odpowiedź. I wreszcie przez ten nifty calculator które również stanowisk wzór następująco:

n = (x 0,3320)/(0,1858 Y)

CCT = 437 * n^3 + 3601 * n^2 + 6861 * n + 5517

Mam nadzieję, że to pomoże każdemu, kto wciąż szuka.