Implementacja CIEDE2000 w bc
| Liczba wizyt | 804 |
|---|---|
| Liczba przeglądanych plików | 317 + 606 |
Na tej stronie przedstawiono referencyjną implementację wzoru na różnicę kolorów CIEDE2000, napisaną w języku programowania bc. Jeśli chcesz zapewnić idealną kompatybilność (do dziesiątego miejsca po przecinku) z niektórymi zewnętrznymi implementacjami, może być konieczne zmodyfikowanie komentarzy w kodzie źródłowym. Aby to ułatwić, poniższy link automatyzuje tę operację.
Funkcja ΔE2000 w bc
Rozważmy bardziej powszechne i akademickie (Sharma, 2005) z dwóch sformułowań.
/* This function written in bc 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. */
m_pi = 0.0
/* 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. */
define ciede_2000(l_1, a_1, b_1, l_2, a_2, b_2) {
/* Working in Basic Calculator 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
if (m_pi == 0.0) {
/* Computing pi ... 3.141592653589793238462643383279502884197169399375105820974945
with arbitrary precision using Machin’s formula proposed in 1706. */
m_pi = 16.0 * a(0.2) - 4.0 * a(1.0 / 239.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)
/* Using 14 lines to simulate atan2, as bc does not have this built-in. */
if (0.0 < a_1) {
h_1 = a(b_1 / (a_1 * n)) + (b_1 < 0.0) * 2.0 * m_pi
} else if (a_1 < 0.0) {
h_1 = a(b_1 / (a_1 * n)) + m_pi
} else {
h_1 = m_pi + ((b_1 < 0.0) - (0.0 < b_1)) * 0.5 * m_pi
}
if (0.0 < a_2) {
h_2 = a(b_2 / (a_2 * n)) + (b_2 < 0.0) * 2.0 * m_pi
} else if (a_2 < 0.0) {
h_2 = a(b_2 / (a_2 * n)) + m_pi
} else {
h_2 = m_pi + ((b_2 < 0.0) - (0.0 < b_2)) * 0.5 * m_pi
}
/* The atan2 polyfill (customized) is complete. */
if (h_2 < h_1) { n = h_1 - h_2; } else { n = h_2 - h_1; }
/* Cross-implementation consistent rounding. */
if (m_pi - 0.00000000000001 < n && n < m_pi + 0.00000000000001) { 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. */
h_m = (h_1 + h_2) * 0.5
h_d = (h_2 - h_1) * 0.5
if (m_pi < n) {
h_d = 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 = h_m + m_pi
/* h_m = h_m + ((h_m < m_pi) - (m_pi <= h_m)) * m_pi */
}
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. */
r_t = -2.0 * sqrt(n / (n + 6103515625.0)) \
* s(m_pi / 3.0 * e(p * p / (-25.0 * m_pi * m_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 * s(2.0 * h_m + m_pi / 2.0) \
+ 0.32 * s(3.0 * h_m + 8.0 * m_pi / 15.0) \
- 0.17 * s(h_m + m_pi / 3.0) \
- 0.20 * s(4.0 * h_m + 3.0 * m_pi / 20.0)
n = c_1 + c_2
/* Hue. */
h = 2.0 * sqrt(c_1 * c_2) * s(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. */
return 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 = 30.8 a1 = 22.0 b1 = -4.4
L2 = 28.1 a2 = 16.4 b2 = 4.3
CIE ΔE00 = 7.0779305175 (Bruce Lindbloom, Netflix’s VMAF, ...)
CIE ΔE00 = 7.0779164917 (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. Podsumowując, współczynniki te wahają się zazwyczaj między 0,5 a 2, przy czym 1 jest wartością najczęściej spotykaną.
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. Przedstawiona tutaj implementacja jest 64-bitowa i zapewnia dokładność na ponad 10 miejsc po przecinku; wybór jednej z formuły zamiast drugiej jest zatem kwestią techniczną. Na górze strony można wybrać jedną z dwóch formuł; obecnie wyświetlana jest formuła uproszczona.
Jak można ustalić, czy dana implementacja CIEDE2000 jest typu akademickiego, czy uproszczonego?
- Oceń
ciede_2000(56.6, 43.6, 41.1, 68.4, 9.4, -8.6) - Jeśli wynik wynosi
30.0001, jest to typ akademicki (jak Sharma, OpenJDK itp.) - Jeśli wynik wynosi
29.9999, jest to typ uproszczony (jak Lindbloom, Netflix VMAF itp.)
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* prawie zawsze mieszczą się w przedziale od -128 do +127, chociaż norma nie określa oficjalnego ograniczenia dla tych dwóch składowych.
| 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 185 i więcej) 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. Gdy wartość ΔE2000 przekracza 40, porównywane kolory nie mają już praktycznie nic wspólnego i nie można z nich wyciągnąć żadnych konkretnych wniosków.
Przykład zastosowania w bc
echo 'scale=50;ciede_2000(13.1, 11.9, 3.8, 13.0, 17.6, -4.9)' | bc -l ciede-2000.bc
# Outputs: 7.37458016458016885544127036110301868134320454640263
# As explained in the comments, compliance with Gaurav Sharma would display ...
# ........ 7.37456659946646273510289154231355556542867583609039Wyniki testów
Ta funkcja bc została przetestowana ze sterownikiem Julia o wielu precyzjach zaprojektowanym do tego celu. Testy te gwarantują, że obliczenia zostaną przeprowadzone bezbłędnie, nawet w krytycznych sytuacjach granicznych, na przykład gdy funkcja arctangens zwraca wartość matematycznie nieokreśloną.
CIEDE2000 Verification Summary :
First Verified Line : 27,-123,101,44,42.0000098,-99,70.204734814936909810694644954670527048474482887
Duration : 18644.34 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9618
Average Deviation : 4.0e-38
Maximum Deviation : 2.2e-35Pliki do pobrania
Poniższy plik obsługuje obliczenia o dowolnej precyzji w bc (przydatne, jeśli masz do czynienia z ΔE2000 w metrologii). Zachęcamy do korzystania z tych plików udostępnionych przez Michela, nawet w celach komercyjnych.
| Plik | Rozmiar | Liczba kliknięć |
|---|---|---|
| ciede-2000.bc | 4 KB | 142 |
| test-bc-arbitrary.yml | 7 KB | 100 |
| test-bc-standard.yml | 5 KB | 75 |
| reference-dataset.txt | 4 KB | 606 |
| Kliknij bc.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ą.