Implementacja CIEDE2000 w TypeScript
| Liczba wizyt | 590 |
|---|---|
| Liczba przeglądanych plików | 355 + 376 |
Ta strona przedstawia referencyjną implementację formuły różnicy kolorów CIEDE2000 w TypeScript. Jeśli chcesz zapewnić idealną kompatybilność (do dziesiątego miejsca po przecinku) z niektórymi implementacjami innych firm, może być konieczne zmodyfikowanie komentarzy w kodzie źródłowym. Aby to ułatwić, poniższy link automatyzuje tę operację.
Funkcja ΔE2000 w TypeScript
Rozważmy bardziej powszechne i akademickie (Sharma, 2005) z dwóch sformułowań.
// This function written in TypeScript 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.
// 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.
function ciede_2000(l_1: number, a_1: number, b_1: number, l_2: number, a_2: number, b_2: number): number {
// Working in TypeScript 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...
const k_l = 1.0, k_c = 1.0, k_h = 1.0;
let 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.
const c_1 = Math.sqrt(a_1 * a_1 * n * n + b_1 * b_1);
const 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.
let h_1 = Math.atan2(b_1, a_1 * n), h_2 = Math.atan2(b_2, a_2 * n);
if (h_1 < 0.0)
h_1 += 2.0 * Math.PI;
if (h_2 < 0.0)
h_2 += 2.0 * Math.PI;
n = Math.abs(h_2 - h_1);
// Cross-implementation consistent rounding.
if (Math.PI - 1E-14 < n && n < Math.PI + 1E-14)
n = Math.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.
let h_m = (h_1 + h_2) * 0.5, h_d = (h_2 - h_1) * 0.5;
if (Math.PI < n) {
h_d += Math.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 += Math.PI;
// h_m += h_m < Math.PI ? Math.PI : -Math.PI;
}
const p = 36.0 * h_m - 55.0 * Math.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.
const r_t = -2.0 * Math.sqrt(n / (n + 6103515625.0))
* Math.sin(Math.PI / 3.0 * Math.exp(p * p / (-25.0 * Math.PI * Math.PI)));
n = (l_1 + l_2) * 0.5;
n = (n - 50.0) * (n - 50.0);
// Lightness.
const 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.
const t = 1.0 + 0.24 * Math.sin(2.0 * h_m + Math.PI * 0.5)
+ 0.32 * Math.sin(3.0 * h_m + 8.0 * Math.PI / 15.0)
- 0.17 * Math.sin(h_m + Math.PI / 3.0)
- 0.20 * Math.sin(4.0 * h_m + 3.0 * Math.PI / 20.0);
n = c_1 + c_2;
// Hue.
const h = 2.0 * Math.sqrt(c_1 * c_2) * Math.sin(h_d) / (k_h * (1.0 + 0.0075 * n * t));
// Chroma.
const 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 = 81.8 a1 = 47.2 b1 = -2.1
// L2 = 82.0 a2 = 41.1 b2 = 2.0
// CIE ΔE00 = 2.9944536917 (Bruce Lindbloom, Netflix’s VMAF, ...)
// CIE ΔE00 = 2.9944393990 (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.Parametry k_l, k_c i k_h
Parametry k_l, k_c i k_h we wzorze CIEDE2000 to współczynniki wagowe stosowane odpowiednio do składowych jasności (ΔL*), chromu (ΔC*) i odcienia (ΔH*). Są one zdefiniowane jako stałe w kodzie źródłowym. W kodzie źródłowym są one zdefiniowane jako stałe z domyślną wartością 1, która odpowiada standardowym warunkom obserwacji określonym przez Międzynarodową Komisję Oświetlenia (CIE). W praktyce może być konieczne dostosowanie tych współczynników w celu odzwierciedlenia określonych warunków: na przykład k_l = 2 jest czasami używane, aby nadać większą wagę różnicom w jasności (powszechne zjawisko w przemyśle tekstylnym), podczas gdy k_c lub k_h można zmniejszyć, aby zwiększyć tolerancję na zmiany nasycenia lub odcienia, w zależności od wymagań. W zależności od kontekstu, współczynniki te zazwyczaj mieszczą się w zakresie od 0,5 do 2.
Dokładność i niezawodność kodu źródłowego
Różnica między akademickim sformułowaniem Sharmy a uproszczonym sformułowaniem Lindblooma nie przekracza ±0,0003 na końcowym ΔE2000. Odpowiada to różnicy zwykle mierzonej między dwiema 32-bitowymi implementacjami i jest niezauważalna dla ludzkiego oka. Nasze 64-bitowe implementacje, wszystkie spójne ze sobą, gwarantują co najmniej 10 poprawnych miejsc po przecinku, więc wybór jednej formuły nad drugą jest szczegółem technicznym. Domyślna formuła na tej stronie jest tą najczęściej prezentowaną w społeczności, jest nieco łatwiejsza do wektoryzacji.
✎ Jeśli zauważycie, że komentarze w kodzie źródłowym nie pokrywają się z komentarzami w języku angielskim, prosimy o poinformowanie autora strony, aby można było to poprawić.
Jak przekonwertować kolory RGB na L*a*b*?
Przejdź do strony AWK, C, Dart, Java, JavaScript, Kotlin, Lua, PHP, Python, Ruby lub Rust, gdzie taki konwerter (wykorzystujący iluminant D65) jest już zaimplementowany oprócz funkcji porównywania kolorów.
Zakresy wartości w CIELAB i interpretacja ΔE2000
W przestrzeni barw CIELAB składnik L* oznacza jasność i zwykle mieści się w zakresie od 0 (czarny) do 100 (biały). Składniki a* i b* opisują osie barw: a* przechodzi od zielonego do czerwonego, a b* od niebieskiego do żółtego. W praktyce wartości a* i b* mieszczą się najczęściej w przedziale od -128 do +127, choć mogą nieznacznie go przekraczać w zależności od konwersji kolorów.
| Kolor 1 | Kolor 2 | Wartość ΔE2000 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
| Kolor 1 | Kolor 2 | Wartość ΔE2000 |
|---|---|---|
| 5 | ||
| 10 | ||
| 15 |
ΔE2000 (CIEDE2000) określa percepcyjną różnicę między dwoma kolorami: 0 oznacza identyczne kolory, a wyższe wartości (do około 185 w skrajnych przypadkach) wskazują na większą różnicę. Na przykład wartość ΔE2000 około 5 oznacza kolory podobne, natomiast około 15 oznacza kolory wyraźnie różne.
Przykład zastosowania w TypeScript
// Example usage of the CIEDE2000 function in TypeScript
const l1 = 17.6, a1 = 39.4, b1 = -1.7;
const l2 = 17.2, a2 = 45.1, b2 = 2.2;
const deltaE: number = ciede_2000(l1, a1, b1, l2, a2, b2);
console.log(deltaE);
// .................................................. This shows a ΔE2000 of 2.8976025528
// As explained in the comments, compliance with Gaurav Sharma would display 2.8976160989Wyniki testów
Sterownik napisany w języku C99, z 250 dokładnymi testami statycznymi, udowodnił, że ta funkcja TypeScript jest interoperacyjna z funkcją CIEDE2000 dostępną w innych językach programowania.
CIEDE2000 Verification Summary :
First Verified Line : 87.51,-44.14,-14,60,53,98.4,58.874366927055824
Duration : 37.78 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9377
Average Deviation : 6.0699611337255987e-15
Maximum Deviation : 2.4158453015843406e-13Pliki do pobrania
Zachęcamy do korzystania z tych plików udostępnionych przez Michela, nawet w celach komercyjnych.
| Plik | Rozmiar | Liczba kliknięć |
|---|---|---|
| ciede-2000.ts | 4 KB | 109 |
| ciede-2000-driver.ts | 5 KB | 95 |
| ciede-2000-random.ts | 6 KB | 92 |
| test-ts.yml | 4 KB | 59 |
| reference-dataset.txt | 4 KB | 376 |
| Kliknij ts.zip, aby pobrać wszystkie pliki w archiwum. | ||
Społeczność
Co sądzisz o tym kodzie źródłowym lub CIEDE2000? Twoja opinia jest dla nas ważna! Księga gości zawiera już 9 wiadomości - w tym 1 w języku polskim. Zajrzyj i podziel się swoją opinią.