Implementacja CIEDE2000 w Pascal
| Liczba wizyt | 462 |
|---|---|
| Liczba przeglądanych plików | 302 + 371 |
Ta strona przedstawia referencyjną implementację formuły różnicy kolorów CIEDE2000 w Pascal. 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 Pascal
Rozważmy bardziej powszechne i akademickie (Sharma, 2005) z dwóch sformułowań.
// This function written in Pascal 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.
uses
Math;
// 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, a_1, b_1, l_2, a_2, b_2: Double): Double;
var
k_l, k_c, k_h, n, c_1, c_2, h_1, h_2, h_m, h_d, p, r_t, l, t, h, c: Double;
begin
// Working in Pascal 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...
k_l := 1.0;
k_c := 1.0;
k_h := 1.0;
n := (sqrt(a_1 * a_1 + b_1 * b_1) + 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 - sqrt(n / (n + 6103515625.0)));
// Application of the chroma correction factor.
c_1 := sqrt(a_1 * a_1 * n * n + b_1 * b_1);
c_2 := 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.
h_1 := arctan2(b_1, a_1 * n);
h_2 := arctan2(b_2, a_2 * n);
if h_1 < 0.0 then h_1 := h_1 + 2.0 * Pi;
if h_2 < 0.0 then h_2 := h_2 + 2.0 * Pi;
n := abs(h_2 - h_1);
// Cross-implementation consistent rounding.
if abs(Pi - n) < 1E-14 then n := 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.
h_m := (h_1 + h_2) * 0.5;
h_d := (h_2 - h_1) * 0.5;
if Pi < n then
begin
h_d := h_d + 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 := h_m + Pi;
// if h_m < Pi then h_m := h_m + Pi else h_m := h_m - Pi;
end;
p := 36.0 * h_m - 55.0 * 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.
r_t := -2.0 * sqrt(n / (n + 6103515625.0))
* sin(Pi / 3.0 * exp(p * p / (-25.0 * Pi * Pi)));
n := (l_1 + l_2) * 0.5;
n := (n - 50.0) * (n - 50.0);
// Lightness.
l := (l_2 - l_1) / (k_l * (1.0 + 0.015 * n / sqrt(20.0 + n)));
// These coefficients adjust the impact of different harmonic
// components on the hue difference calculation.
t := 1.0 + 0.24 * sin(2.0 * h_m + Pi / 2.0)
+ 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);
n := c_1 + c_2;
// Hue.
h := 2.0 * sqrt(c_1 * c_2) * sin(h_d) / (k_h * (1.0 + 0.0075 * n * t));
// Chroma.
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.
Exit(sqrt(l * l + h * h + c * c + c * h * r_t));
end;
// GitHub Project : https://github.com/michel-leonard/ciede2000-color-matching
// Online Tests : https://michel-leonard.github.io/ciede2000-color-matching
// L1 = 40.9 a1 = 22.7 b1 = 4.1
// L2 = 41.1 a2 = 28.1 b2 = -3.6
// CIE ΔE00 = 5.6213040434 (Bruce Lindbloom, Netflix’s VMAF, ...)
// CIE ΔE00 = 5.6212902503 (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 w CIEDE2000 są współczynnikami wagowymi stosowanymi do pojęć jasności (ΔL*), barwy (ΔC*) i odcienia (ΔH*). Są one zdefiniowane jako stałe w kodzie źródłowym. Ich domyślną wartością jest 1, co odpowiada standardowym warunkom oglądania zalecanym 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 znajdziesz komentarz w kodzie źródłowym, który nie jest zgodny z innym językiem, poinformuj o tym autora strony, aby można było wprowadzić poprawkę.
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 Pascal
// Calculate ΔE*00 between two colors in L*a*b* space
var
l1, a1, b1, l2, a2, b2, deltaE: Double;
begin
l1 := 31.8; a1 := 22.9; b1 := 4.8;
l2 := 30.2; a2 := 18.7; b2 := -3.7;
deltaE := ciede_2000(l1, a1, b1, l2, a2, b2);
writeln('CIEDE2000 = ', deltaE:0:10);
end.
// .................................................. This shows a ΔE2000 of 6.1884550095
// As explained in the comments, compliance with Gaurav Sharma would display 6.1884708040Wyniki testów
Sterownik napisany w języku C99, z 250 dokładnymi testami statycznymi, udowodnił, że ta funkcja Pascal jest interoperacyjna z funkcją CIEDE2000 dostępną w innych językach programowania.
CIEDE2000 Verification Summary :
First Verified Line : 89.9,44,33,7,-75.04,-57,120.27117304507197559
Duration : 33.38 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9452
Average Deviation : 1.4059798381094168e-14
Maximum Deviation : 3.4106051316484809e-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.pas | 4 KB | 98 |
| ciede-2000-driver.pas | 5 KB | 79 |
| ciede-2000-random.pas | 6 KB | 78 |
| test-pas.yml | 3 KB | 47 |
| reference-dataset.txt | 4 KB | 371 |
| Kliknij pas.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ą.