Implementación de CIEDE2000 en SQL
| Número de visitas | 425 |
|---|---|
| Número de archivos consultados | 250 + 313 |
Esta página presenta una implementación de referencia de la fórmula de diferencia de color CIEDE2000 en SQL. Si desea obtener una coincidencia exacta con implementaciones de terceros de hasta 10 decimales, es posible que tenga que realizar algunos cambios en el código fuente, en particular comentando y descomentando algunas líneas, que pueden aplicarse automáticamente a través del siguiente enlace.
La función ΔE2000 en SQL
Consideremos la más común y académica (Sharma, 2005) de las dos formulaciones.
-- Esta función escrita en SQL es de dominio público y no
-- está afiliada a la CIE (Comisión Internacional de Iluminación).
DELIMITER //
-- Eliminar cualquier función del mismo nombre que ya exista
DROP FUNCTION IF EXISTS ciede_2000 //
-- La implementación clásica de CIEDE2000 que recibe dos colores L*a*b* y devuelve su diferencia.
-- El componente "L" varía de 0 a 100. "a" y "b" normalmente se proyectan entre -128 y 127.
CREATE FUNCTION ciede_2000(l_1 DOUBLE, a_1 DOUBLE, b_1 DOUBLE, l_2 DOUBLE, a_2 DOUBLE, b_2 DOUBLE)
RETURNS DOUBLE
DETERMINISTIC
NO SQL
BEGIN
-- Ejecuta el cálculo de diferencia de color CIEDE2000 en SQL/PSM.
-- k_l, k_c y k_h son factores paramétricos a ajustar según
-- sus necesidades de visualización (texturas, fondos).
DECLARE k_l, k_c, k_h DOUBLE DEFAULT 1.0;
DECLARE n, c_1, c_2, h_1, h_2, h_m, h_d, r_t, p, t, l, c, h DOUBLE;
SET n = (SQRT(a_1 * a_1 + b_1 * b_1) + SQRT(a_2 * a_2 + b_2 * b_2)) * 0.5;
SET n = n * n * n * n * n * n * n;
-- Un factor que implica la croma elevada a la potencia 7,
-- diseñado para tener más en cuenta la influencia de la croma.
SET n = 1.0 + 0.5 * (1.0 - SQRT(n / (n + 6103515625.0)));
-- Aplicación del factor de corrección de la croma para compensar su no linealidad.
SET c_1 = SQRT(a_1 * a_1 * n * n + b_1 * b_1);
SET c_2 = SQRT(a_2 * a_2 * n * n + b_2 * b_2);
-- La función atan2 es preferible a atan porque calcula el ángulo de un
-- punto (x, y) en todos los cuadrantes, teniendo en cuenta el signo de x e y.
SET h_1 = COALESCE(ATAN2(b_1, a_1 * n), 0);
SET h_2 = COALESCE(ATAN2(b_2, a_2 * n), 0);
IF h_1 < 0 THEN SET h_1 = h_1 + 2 * PI(); END IF;
IF h_2 < 0 THEN SET h_2 = h_2 + 2 * PI(); END IF;
SET n = ABS(h_2 - h_1);
-- Evita que la rama dependa del RoundingMode del lenguaje de programación.
IF PI() - 1E-14 < n AND n < PI() + 1E-14 THEN SET n = PI(); END IF;
-- Cuando los ángulos de tono se encuentran en diferentes cuadrantes,
-- la media aritmética simple puede dar un ángulo incorrecto, las
-- líneas siguientes aplican la corrección angular necesaria.
SET h_m = (h_1 + h_2) * 0.5;
SET h_d = (h_2 - h_1) * 0.5;
IF PI() < n THEN
SET h_d = h_d + PI();
-- 📜 La formulación de Sharma no utiliza la línea siguiente, sino la que le sigue.
-- Nota: estas dos variantes sólo difieren en ±0,0003 en la diferencia de color final.
SET h_m = h_m + PI();
-- SET h_m = h_m + CASE WHEN h_m < PI() THEN PI() ELSE -PI() END;
END IF;
SET p = 36.0 * h_m - 55.0 * PI();
SET n = (c_1 + c_2) * 0.5;
SET n = n * n * n * n * n * n * n;
-- El término de corrección de la rotación del tono mejora la precisión
-- del algoritmo, especialmente cuando la comparación se refiere a azules.
SET r_t = -2.0 * SQRT(n / (n + 6103515625.0)) * SIN(PI() / 3.0 * EXP(p * p / (-25.0 * PI() * PI())));
SET n = (l_1 + l_2) * 0.5;
SET n = (n - 50.0) * (n - 50.0);
-- Luminosidad .
SET l = (l_2 - l_1) / (k_l * (1.0 + 0.015 * n / SQRT(20.0 + n)));
-- Estos coeficientes se utilizan para modular la influencia de
-- los componentes armónicos en el cálculo de la diferencia de tono.
SET t = 1.0 + 0.24 * SIN(2.0 * h_m + PI() * 0.5)
+ 0.32 * SIN(3.0 * h_m + 8.0 * PI() / 15.0)
- 0.17 * SIN(h_m + PI() / 3.0)
- 0.20 * SIN(4.0 * h_m + 3.0 * PI() / 20.0);
SET n = c_1 + c_2;
-- Tono.
SET h = 2.0 * SQRT(c_1 * c_2) * SIN(h_d) / (k_h * (1.0 + 0.0075 * n * t));
-- Croma.
SET c = (c_2 - c_1) / (k_c * (1.0 + 0.0225 * n));
-- Devolver la raíz cuadrada garantiza que dE00 representa una distancia
-- geométrica (que va de 0 a aproximadamente 185) en el espacio CIELAB.
RETURN SQRT(l * l + h * h + c * c + c * h * r_t);
END //
DELIMITER ;
-- Proyecto GitHub : https://github.com/michel-leonard/ciede2000-color-matching
-- Pruebas en línea : https://michel-leonard.github.io/ciede2000-color-matching
-- L1 = 52.3 a1 = 21.9 b1 = 2.7
-- L2 = 53.8 a2 = 28.0 b2 = -3.1
-- CIE ΔE00 = 5.0119430211 (Bruce Lindbloom, Netflix’s VMAF, ...)
-- CIE ΔE00 = 5.0119254601 (Gaurav Sharma, OpenJDK, ...)
-- Desviación entre implementaciones ≈ 1.8e-5
-- Consulte los comentarios del código fuente para pasar de una de estas variantes de implementación ΔE*00 a la otra.Precisión y fiabilidad del código fuente
La diferencia entre las formulaciones de Sharma y Lindbloom nunca excede ±0,0003 en el ΔE2000 final, lo que corresponde a la diferencia habitual medida entre dos implementaciones de 32 bits y es imperceptible al ojo humano. Nuestras implementaciones de 64 bits, todas coherentes entre sí, garantizan al menos 10 decimales correctos, por lo que elegir una formulación u otra depende principalmente de la interoperabilidad deseada. La formulación que aparece por defecto en esta página es la más utilizada (su microventaja es que se basa en la comunidad y es más ligera que su análoga cuando se vectoriza).
✎ Si encuentra un comentario en el código fuente que no corresponde a otro idioma, informe al autor del sitio, que estudiará su sugerencia y la incorporará al código fuente.
¿Cómo se convierten los colores RGB a L*a*b*?
Vaya a la página AWK, C, Dart, Java, JavaScript, Kotlin, Lua, PHP, Python, Ruby o Rust, donde ya está implementado dicho conversor (que utiliza el iluminante D65), además de la función de comparación de colores.
Rangos de valores en CIELAB e interpretación del ΔE2000
En el espacio de color CIELAB, el componente L* representa la luminosidad y suele variar de 0 (negro) a 100 (blanco). Los componentes a* y b* definen los ejes de color: a* va del verde al rojo, y b* del azul al amarillo. En la práctica, a* y b* se encuentran normalmente entre -128 y +127, aunque pueden superar ligeramente estos límites según la conversión de color.
| Color 1 | Color 2 | Valor de ΔE2000 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
| Color 1 | Color 2 | Valor de ΔE2000 |
|---|---|---|
| 5 | ||
| 10 | ||
| 15 |
ΔE2000 (CIEDE2000) cuantifica la diferencia perceptible entre dos colores: 0 significa que son idénticos, y valores más altos (hasta aproximadamente 185 en casos extremos) indican una diferencia más notable. Por ejemplo, un ΔE2000 alrededor de 5 indica colores cercanos, mientras que alrededor de 15 indica colores claramente distintos.
Ejemplo de uso en SQL
-- Example usage of the ΔE*00 function in SQL
-- Color 1: l1 = 94.1 a1 = 30.7 b1 = 2.9
-- Color 2: l2 = 92.2 a2 = 26.4 b2 = -2.2
SELECT ciede_2000(l1, a1, b1, l2, a2, b2) AS delta_e;
-- .................................................. This shows a ΔE2000 of 3.8819773139
-- As explained in the comments, compliance with Gaurav Sharma would display 3.8819904826Los resultados de las pruebas
El controlador escrito en lenguaje C99, con 250 pruebas estáticas precisas, ha demostrado que esta función SQL es interoperable con la función CIEDE2000 disponible en otros lenguajes de programación.
CIEDE2000 Verification Summary :
First Verified Line : 57.7,61,95.1,50.49,-53,-91.7,72.48542739412765
Duration : 44.06 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9405
Average Deviation : 4.2545206732635951e-15
Maximum Deviation : 1.1368683772161603e-13Archivos para descargar
Siéntase libre de utilizar estos archivos puestos a disposición por Michel, incluso con fines comerciales.
| Archivo | Tamaño | Número de clics |
|---|---|---|
| ciede-2000.sql | 4 KB | 69 |
| ciede-2000.pg.sql | 4 KB | 72 |
| test-sql-mariadb.yml | 5 KB | 50 |
| test-sql-postgresql.yml | 3 KB | 59 |
| reference-dataset.txt | 4 KB | 313 |
| Haga clic en sql.zip para descargar todos estos archivos en un archivo. | ||
Comunidad
Si quieres dejar tu opinión sobre este código fuente SQL o sobre CIEDE2000 en general, el libro de visitas ya contiene 1 mensajes en español, y 9 mensajes en total, así que dinos lo que piensas.