Implementação do CIEDE2000 em Haxe
| Número de visitas | 417 |
|---|---|
| Número de arquivos visualizados | 290 + 398 |
Esta página apresenta uma implementação de referência da fórmula de diferença de cor CIEDE2000 em Haxe. Se quiser assegurar uma compatibilidade perfeita (até à décima casa decimal) com algumas implementações de terceiros, poderá ter de modificar os comentários no código fonte. Para facilitar isto, a seguinte ligação automatiza esta operação.
A função ΔE2000 em Haxe
Consideremos a mais comum e académica (Sharma, 2005) das duas formulações.
// This function written in Haxe is not affiliated with the CIE (International Commission on Illumination),
// and is released into the public domain. It is provided "as is" without any warranty, express or implied.
// Expressly defining pi ensures that the code works on different platforms.
public static inline var M_PI:Float = 3.14159265358979323846264338328;
// The classic CIE ΔE2000 implementation, which operates on two L*a*b* colors, and returns their difference.
// "l" ranges from 0 to 100, while "a" and "b" are unbounded and commonly clamped to the range of -128 to 127.
public static function ciede_2000(l_1:Float, a_1:Float, b_1:Float, l_2:Float, a_2:Float, b_2:Float):Float {
// Working in Haxe with the CIEDE2000 color-difference formula.
// k_l, k_c, k_h are parametric factors to be adjusted according to
// different viewing parameters such as textures, backgrounds...
var k_l = 1.0;
var k_c = 1.0;
var k_h = 1.0;
var n = (Math.sqrt(a_1 * a_1 + b_1 * b_1) + Math.sqrt(a_2 * a_2 + b_2 * b_2)) * 0.5;
n = n * n * n * n * n * n * n;
// A factor involving chroma raised to the power of 7 designed to make
// the influence of chroma on the total color difference more accurate.
n = 1.0 + 0.5 * (1.0 - Math.sqrt(n / (n + 6103515625.0)));
// Application of the chroma correction factor.
var c_1 = Math.sqrt(a_1 * a_1 * n * n + b_1 * b_1);
var c_2 = Math.sqrt(a_2 * a_2 * n * n + b_2 * b_2);
// atan2 is preferred over atan because it accurately computes the angle of
// a point (x, y) in all quadrants, handling the signs of both coordinates.
var h_1 = Math.atan2(b_1, a_1 * n);
var h_2 = Math.atan2(b_2, a_2 * n);
if (h_1 < 0.0) h_1 += 2.0 * M_PI;
if (h_2 < 0.0) h_2 += 2.0 * M_PI;
n = Math.abs(h_2 - h_1);
// Cross-implementation consistent rounding.
if (M_PI - 1E-14 < n && n < M_PI + 1E-14) n = M_PI;
// When the hue angles lie in different quadrants, the straightforward
// average can produce a mean that incorrectly suggests a hue angle in
// the wrong quadrant, the next lines handle this issue.
var h_m = (h_1 + h_2) * 0.5;
var h_d = (h_2 - h_1) * 0.5;
if (M_PI < n) {
h_d += M_PI;
// 📜 Sharma’s formulation doesn’t use the next line, but the one after it,
// and these two variants differ by ±0.0003 on the final color differences.
h_m += M_PI;
// h_m += h_m < M_PI ? M_PI : -M_PI;
}
var p = 36.0 * h_m - 55.0 * M_PI;
n = (c_1 + c_2) * 0.5;
n = n * n * n * n * n * n * n;
// The hue rotation correction term is designed to account for the
// non-linear behavior of hue differences in the blue region.
var r_t = -2.0 * Math.sqrt(n / (n + 6103515625.0))
* Math.sin(M_PI / 3.0 * Math.exp(p * p / (-25.0 * M_PI * M_PI)));
n = (l_1 + l_2) * 0.5;
n = (n - 50.0) * (n - 50.0);
// Lightness.
var l = (l_2 - l_1) / (k_l * (1.0 + 0.015 * n / Math.sqrt(20.0 + n)));
// These coefficients adjust the impact of different harmonic
// components on the hue difference calculation.
var t = 1.0 + 0.24 * Math.sin(2.0 * h_m + M_PI / 2.0)
+ 0.32 * Math.sin(3.0 * h_m + 8.0 * M_PI / 15.0)
- 0.17 * Math.sin(h_m + M_PI / 3.0)
- 0.20 * Math.sin(4.0 * h_m + 3.0 * M_PI / 20.0);
n = c_1 + c_2;
// Hue.
var h = 2.0 * Math.sqrt(c_1 * c_2) * Math.sin(h_d) / (k_h * (1.0 + 0.0075 * n * t));
// Chroma.
var c = (c_2 - c_1) / (k_c * (1.0 + 0.0225 * n));
// Returning the square root ensures that dE00 accurately reflects the
// geometric distance in color space, which can range from 0 to around 185.
return Math.sqrt(l * l + h * h + c * c + c * h * r_t);
}
// GitHub Project : https://github.com/michel-leonard/ciede2000-color-matching
// Online Tests : https://michel-leonard.github.io/ciede2000-color-matching
// L1 = 44.6 a1 = 19.9 b1 = 5.5
// L2 = 45.1 a2 = 14.6 b2 = -3.1
// CIE ΔE00 = 6.7625351227 (Bruce Lindbloom, Netflix’s VMAF, ...)
// CIE ΔE00 = 6.7625487710 (Gaurav Sharma, OpenJDK, ...)
// Deviation between implementations ≈ 1.4e-5
// See the source code comments for easy switching between these two widely used ΔE*00 implementation variants.Parâmetros k_l, k_c e k_h
Os parâmetros k_l, k_c e k_h na fórmula CIEDE2000 são factores de ponderação aplicados aos componentes de brilho (ΔL*), croma (ΔC*) e matiz (ΔH*), respetivamente. São definidos como constantes no código fonte. No código-fonte, são definidos como constantes com um valor por defeito de 1, que corresponde às condições de observação padrão estabelecidas pela Comissão Internacional da Iluminação (CIE). Na prática, pode ser necessário ajustar estes coeficientes para refletir condições específicas: por exemplo, k_l = 2 é por vezes utilizado para dar mais peso a diferenças de brilho (uma ocorrência comum na indústria têxtil), enquanto k_c ou k_h podem ser reduzidos para aumentar a tolerância a variações de saturação ou matiz. Em resumo, estes coeficientes variam normalmente entre 0,5 e 2, sendo 1 o valor mais comum.
Precisão e fiabilidade do código fonte
A diferença entre a formulação académica de Sharma e a formulação simplificada de Lindbloom não excede ±0,0003 no ΔE2000 final. A implementação aqui apresentada é de 64 bits e garante uma precisão superior a 10 casas decimais; a escolha de uma formulação em detrimento de outra é, portanto, um pormenor técnico. No topo desta página, pode escolher entre as duas formulações; a que está atualmente a ser apresentada é a formulação simplificada.
Como determinar se uma determinada implementação do CIEDE2000 é acadêmica ou simplificada?
- Avaliem
ciede_2000(79.6,104.7,23.3,63.4,65.1,-14.3) - Se o resultado for
20.00002, trata-se do tipo acadêmico (como Sharma, OpenJDK, etc.) - Se o resultado for
19.99997, trata-se do tipo simplificado (como Lindbloom, Netflix VMAF, etc.)
Como é que se convertem cores RGB em L*a*b*?
Vá para a página AWK, C, Dart, Java, JavaScript, Kotlin, Lua, PHP, Python, Ruby ou Rust onde esse conversor (utilizando o iluminante D65) já está implementado para além da função de comparação de cores.
Intervalos de valores no CIELAB e interpretação do ΔE2000
No espaço de cor CIELAB, o componente L* representa a luminosidade e normalmente varia de 0 (preto) a 100 (branco). Os componentes a* e b* representam os eixos de cor: a* vai do verde ao vermelho, enquanto b* vai do azul ao amarelo. Na prática, os valores de a* e b* estão quase sempre limitados a um intervalo entre -128 e +127, embora a norma não especifique um limite oficial para estes dois componentes.
| Cor 1 | Cor 2 | Valor de ΔE2000 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
| Cor 1 | Cor 2 | Valor de ΔE2000 |
|---|---|---|
| 5 | ||
| 10 | ||
| 15 |
ΔE2000 (CIEDE2000) mede a diferença perceptível entre duas cores: 0 significa cores idênticas, e valores maiores (até 185 e mais) indicam uma diferença mais significativa. Por exemplo, um valor ΔE2000 em torno de 5 indica cores próximas, enquanto em torno de 15 indica cores claramente diferentes. Quando o valor ΔE2000 ultrapassa 40, as cores comparadas já não têm praticamente nada em comum, e não é possível obter informações precisas a partir delas.
Exemplo de utilização em Haxe
// Compute the Delta E (CIEDE2000) color difference between two L*a*b* colors in Haxe
// Color 1: l1 = 64.9 a1 = 12.6 b1 = 3.0
// Color 2: l2 = 66.8 a2 = 18.3 b2 = -4.3
var deltaE: Float = ciede_2000(l1, a1, b1, l2, a2, b2);
trace(deltaE);
// .................................................. This shows a ΔE2000 of 6.6360262302
// As explained in the comments, compliance with Gaurav Sharma would display 6.6360100975Resultados dos testes
O nosso programa de testes, escrito em C99, inclui 250 testes estáticos precisos. Os resultados mostram que esta função do CIEDE2000 em Haxe é interoperável com as outras 41 linguagens de programação.
CIEDE2000 Verification Summary :
First Verified Line : 11,-68.86,59.9,1,-69.38,-117.7,66.5323051729542101
Duration : 136.05 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9504
Average Deviation : 4.2509125594558664e-15
Maximum Deviation : 1.1368683772161603e-13Ficheiros para descarregar
Pode utilizar livremente estes ficheiros disponibilizados pelo Michel, mesmo para fins comerciais.
| Arquivo | Tamanho | Número de cliques |
|---|---|---|
| ciede-2000.hx | 4 KB | 87 |
| ciede-2000-driver.hx | 6 KB | 86 |
| ciede-2000-random.hx | 6 KB | 75 |
| test-hx.yml | 4 KB | 42 |
| reference-dataset.txt | 4 KB | 398 |
| Clique em hx.zip para baixar todos estes arquivos em um arquivo. | ||
Comunidade
O que pensa deste código fonte ou do CIEDE2000? A sua opinião é importante para nós! O livro de visitas já contém 9 mensagens - incluindo 1 em português. Dê uma vista de olhos e partilhe a sua opinião.