php - significa - Calcular la temperatura de color en K
temperatura de color fotografia (5)
Basado en el artículo de Wikipedia ingresé la fórmula aproximada para el cálculo de la Color Temperature
en Excel como
=(-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
¡Funciona bien!
He escrito una biblioteca para trabajar con colores y me he quedado atascado tratando de calcular Tc(k)
. De lo que he leído trabajando en el espacio de color XYZ
CIE 1931 es el camino a seguir y puede obtenerse utilizando xyY
.
Hasta ahora, tengo todo correcto hasta el punto de averiguar la x
y la correcta de:
X Y
x = ____________ y = ____________
( X + Y + Z) ( X + Y + Z)
Los números están muy arriba de la tabla, pero no se puede encontrar nada que detalle cómo pasas de x
e y
a Tc(K)
Por ejemplo: para # FF0000 obtengo lo siguiente.
x: 0.64007449945677
y: 0.32997051063169
He leído varios artículos sobre el tema y, literalmente, todos los artículos de wikipedia. Todas las preguntas que he encontrado en SO simplemente enlazan a un artículo de wiki sobre colores, no se ve uno que tenga la fórmula real para calcular Tc(k)
Hice algunas excavaciones en algunas aplicaciones de código abierto y encontré algo en UFRaw. No he descubierto exactamente qué está pasando exactamente.
También encontré un paper que parece cubrir el tema bastante bien.
Convertido a PHP y esto es lo que tengo hasta ahora:
$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);
}
Mi salida:
Bastante cerca pero no 100% todavía. (Encontré un bug en mi código y ahora es casi perfecto)
- Los colores están ligeramente fuera de k -> rgb
- No funciona haciendo k -> rgb -> k. No vuelves al mismo valor.
Código
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;
}
La Wikipedia establece que la temperatura del color se calcula teniendo en cuenta las cromaticidades uv, no xy, por lo que debe realizar una traducción. Dicho esto, recomiendo usar una aproximación (también explicada en la Wikipedia) como lo sugiere @sixlettervariables.
La verdadera pregunta es, ¿de qué estás tratando de encontrar la temperatura del color? Veo una referencia (# FF0000) a los colores RGB, que no tienen sentido sin indicar un espacio de color. Suponiendo que está en sRGB (para que pueda señalarle Wikipedia nuevamente), primero debe obtener las coordenadas RGB lineales antes de pasar a XYZ.
Me doy cuenta de que esta es una vieja pregunta, pero también estaba luchando para encontrar una respuesta. Finalmente encontré esta ingeniosa calculadora que también publica la fórmula de la siguiente manera:
n = (x-0.3320) / (0.1858-y)
CCT = 437 * n ^ 3 + 3601 * n ^ 2 + 6861 * n + 5517
Espero que esto ayude a cualquiera que todavía esté mirando.
Si le entiendo correctamente, consulte este pdf donde se describen varios métodos (brevemente :(). Desde este PDF:
[CCT1] Los cálculos se realizan usando las coordenadas de espacio de color uniforme CIE 1960 y v. Las coordenadas u y v se derivan de x e y usando las fórmulas: u = 4x / (12y-2x + 3) y v = 6y / (12y- 2x + 3) La temperatura de color correlacionada se define como la temperatura de un cuerpo negro que se encuentra más cerca de las coordenadas u, v de la fuente de prueba. Dos métodos separados proporcionan resultados: uno es un método iterativo basado en la definición, y el otro es el método de Robertson utilizado comúnmente que involucra la interpolación basada en una tabla de 30 parámetros precalculados de u, v y de pendiente inversa. Iteración Si uS y vS son los valores para una fuente de prueba, y uT y vT son los valores de cuerpo negro a temperatura T, la temperatura de color correlacionada es el valor de T donde:
sqrt( (uS - uT)^2 + (vS - vT)^2 )
se minimiza. El ajuste de la temperatura T para obtener el mínimo de esta función se realizó utilizando hojas de cálculo (Quattro Pro 8 y Excel 97). Ambas hojas de cálculo dieron valores idénticos.
No sé si realmente te ayuda.