Implementazione di CIEDE2000 in Fortran
| Numero di visite | 496 |
|---|---|
| Numero di file visualizzati | 279 + 374 |
Questa pagina presenta unโimplementazione di riferimento della formula della differenza di colore CIEDE2000 in Fortran. Se si vuole garantire la perfetta compatibilitร (con la decima cifra decimale) con alcune implementazioni di terze parti, potrebbe essere necessario modificare i commenti nel codice sorgente. Per facilitare questa operazione, il seguente link la automatizza.
La funzione ΔE2000 in Fortran
Consideriamo la piรน comune e accademica (Sharma, 2005) delle due formulazioni.
! This function written in Fortran 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.
module ciede_2000_module
use iso_fortran_env, only: real64
implicit none
private
public :: ciede_2000
real(kind=real64), parameter :: M_PI = 3.14159265358979323846264338328_real64
! k_l, k_c, k_h are parametric factors to be adjusted according to
! different viewing parameters such as textures, backgrounds...
real(kind=real64), parameter :: k_l = 1.0_real64, k_c = 1.0_real64, k_h = 1.0_real64
contains
! 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) result(delta_e)
implicit none
real(kind=real64), intent(in) :: l_1, a_1, b_1, l_2, a_2, b_2
real(kind=real64) :: n, c_1, c_2, h_1, h_2, h_m, h_d, p, r_t, l, t, h, c, delta_e
! Working in Fortran with the CIEDE2000 color-difference formula.
n = (sqrt(a_1 * a_1 + b_1 * b_1) + sqrt(a_2 * a_2 + b_2 * b_2)) * 0.5_real64
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_real64 + 0.5_real64 * (1.0_real64 - sqrt(n / (n + 6103515625.0_real64)))
! 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 = atan2(b_1, a_1 * n)
h_2 = atan2(b_2, a_2 * n)
if (h_1 < 0.0_real64) h_1 = h_1 + 2.0_real64 * M_PI
if (h_2 < 0.0_real64) h_2 = h_2 + 2.0_real64 * M_PI
n = abs(h_2 - h_1)
! Cross-implementation consistent rounding.
if (M_PI - 0.00000000000001_real64 < n .and. n < M_PI + 0.00000000000001_real64) 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_real64
h_d = (h_2 - h_1) * 0.5_real64
if (M_PI < n) then
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 + MERGE(M_PI, -M_PI, h_m < M_PI)
endif
p = 36.0_real64 * h_m - 55.0_real64 * M_PI
n = (c_1 + c_2) * 0.5_real64
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_real64 * sqrt(n / (n + 6103515625.0_real64)) &
* sin(M_PI / 3.0_real64 * exp(p * p / (-25.0_real64 * M_PI * M_PI)))
n = (l_1 + l_2) * 0.5_real64
n = (n - 50.0_real64) * (n - 50.0_real64)
! Lightness.
l = (l_2 - l_1) / (k_l * (1.0_real64 + 0.015_real64 * n / sqrt(20.0_real64 + n)))
! These coefficients adjust the impact of different harmonic
! components on the hue difference calculation.
t = 1.0_real64 + 0.24_real64 * sin(2.0_real64 * h_m + M_PI / 2.0_real64) &
+ 0.32_real64 * sin(3.0_real64 * h_m + 8.0_real64 * M_PI / 15.0_real64) &
- 0.17_real64 * sin(h_m + M_PI / 3.0_real64) &
- 0.20_real64 * sin(4.0_real64 * h_m + 3.0_real64 * M_PI / 20.0_real64)
n = c_1 + c_2
! Hue.
h = 2.0_real64 * sqrt(c_1 * c_2) * sin(h_d) / (k_h * (1.0_real64 + 0.0075_real64 * n * t))
! Chroma.
c = (c_2 - c_1) / (k_c * (1.0_real64 + 0.0225_real64 * n))
! Returning the square root ensures that dE00 accurately reflects the
! geometric distance in color space, which can range from 0 to around 185.
delta_e = sqrt(l * l + h * h + c * c + c * h * r_t)
end function ciede_2000
end module ciede_2000_module
! GitHub Project : https://github.com/michel-leonard/ciede2000-color-matching
! Online Tests : https://michel-leonard.github.io/ciede2000-color-matching
! L1 = 68.5 a1 = 18.1 b1 = 3.6
! L2 = 70.2 a2 = 23.8 b2 = -4.0
! CIE ฮE00 = 6.1142357448 (Bruce Lindbloom, Netflixโs VMAF, ...)
! CIE ฮE00 = 6.1142186799 (Gaurav Sharma, OpenJDK, ...)
! Deviation between implementations โ 1.7e-5
! See the source code comments for easy switching between these two widely used ฮE*00 implementation variants.Parametri k_l, k_c e k_h
I parametri k_l, k_c e k_h in CIEDE2000 sono fattori di ponderazione applicati ai termini luminositร (ฮL*), croma (ฮC*) e tinta (ฮH*). Sono definiti come costanti nel codice sorgente. Il loro valore predefinito รจ 1, che corrisponde alle condizioni di visualizzazione standard raccomandate dalla Commissione internazionale per lโilluminazione (CIE). In pratica, potrebbe essere necessario regolare questi coefficienti per riflettere condizioni specifiche: ad esempio, k_l = 2 viene talvolta utilizzato per dare maggior peso alle differenze di luminositร (un caso comune nellโindustria tessile), mentre k_c o k_h possono essere ridotti per aumentare la tolleranza alle variazioni di saturazione o di tonalitร , a seconda delle esigenze. A seconda del contesto, questi coefficienti variano in genere da 0,5 a 2.
Precisione e affidabilitร del codice sorgente
La differenza tra la formulazione accademica di Sharma e quella semplificata di Lindbloom non supera ยฑ0,0003 sul ฮE2000 finale. Ciรฒ corrisponde alla differenza solitamente misurata tra due implementazioni a 32 bit ed รจ impercettibile allโocchio umano. Le nostre implementazioni a 64 bit, tutte coerenti tra loro, garantiscono almeno 10 cifre decimali corrette, quindi la scelta di una formulazione rispetto allโaltra รจ un dettaglio tecnico. La formula predefinita in questa pagina รจ quella presentata piรน spesso nella comunitร , รจ leggermente piรน facile da vettorializzare.
โ Se notate che i commenti nel codice sorgente non corrispondono ai commenti in inglese, siete pregati di informare lโautore della pagina in modo da poterli correggere.
Come si convertono i colori RGB in L*a*b*?
Andate alla pagina AWK, C, Dart, Java, JavaScript, Kotlin, Lua, PHP, Python, Ruby o Rust dove tale convertitore (che utilizza lโilluminante D65) รจ giร implementato in aggiunta alla funzione di confronto dei colori.
Intervalli di valori in CIELAB e interpretazione del ฮE2000
Nello spazio colore CIELAB, la componente L* rappresenta la luminositร e varia tipicamente da 0 (nero) a 100 (bianco). Le componenti a* e b* definiscono gli assi cromatici: a* va dal verde al rosso, mentre b* va dal blu al giallo. In pratica, i valori di a* e b* si collocano solitamente tra -128 e +127, anche se possono superare leggermente questi limiti in base alle conversioni cromatiche.
| Colore 1 | Colore 2 | Valore di ฮE2000 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
| Colore 1 | Colore 2 | Valore di ฮE2000 |
|---|---|---|
| 5 | ||
| 10 | ||
| 15 |
ฮE2000 (CIEDE2000) misura la differenza percepita tra due colori: 0 significa colori identici, e valori piรน alti (fino a circa 185 nei casi estremi) indicano una differenza piรน evidente. Per esempio, un ฮE2000 intorno a 5 indica colori vicini, mentre intorno a 15 indica colori chiaramente distinti.
Esempio di utilizzo in Fortran
! Compute the Delta E (CIEDE2000) color difference between two L*a*b* colors in Fortran
! Color 1: l1 = 89.0 a1 = 33.3 b1 = -1.7
! Color 2: l2 = 89.2 a2 = 38.4 b2 = 2.2
delta_e = ciede_2000(l1, a1, b1, l2, a2, b2)
print '(F0.10)', delta_e
! .................................................. This shows a ΔE2000 of 2.9929564263
! As explained in the comments, compliance with Gaurav Sharma would display 2.9929700654I risultati dei test
Il driver scritto in linguaggio C99, con 250 test statici precisi, ha dimostrato che questa funzione Fortran รจ interoperabile con la funzione CIEDE2000 disponibile in altri linguaggi di programmazione.
CIEDE2000 Verification Summary :
First Verified Line : 24,122.6,117,21,-40.999999999847,-46,81.762663548041459
Duration : 41.38 s
Successes : 10000000
Errors : 0
Average Delta E : 63.2338
Average Deviation : 4.6e-15
Maximum Deviation : 1.1e-13File da scaricare
Sentitevi liberi di utilizzare questi file messi a disposizione da Michel, anche per scopi commerciali.
| File | Dimensione | Numero di clic |
|---|---|---|
| ciede-2000.f90 | 5 KB | 82 |
| ciede-2000-driver.f90 | 6 KB | 73 |
| ciede-2000-random.f90 | 7 KB | 79 |
| test-f90.yml | 3 KB | 45 |
| reference-dataset.txt | 4 KB | 374 |
| Fai clic su f90.zip per scaricare tutti i file in un archivio. | ||
Comunitร
Cosa ne pensate di questo codice sorgente o di CIEDE2000? La vostra opinione รจ importante per noi! Il libro degli ospiti contiene giร 9 messaggi, di cui 1 in italiano. Date unโocchiata e condividete la vostra opinione.