CIEDE2000-Implementierung in C
| Anzahl der Besuche | 830 |
|---|---|
| Anzahl der angesehenen Dateien | 876 + 371 |
Diese Seite enthĂ€lt eine Referenzimplementierung der CIEDE2000 Formel fĂŒr den Farbabstand in C. Wenn Sie eine perfekte KompatibilitĂ€t (bis zur zehnten Dezimalstelle) mit einigen Implementierungen von Drittanbietern sicherstellen wollen, mĂŒssen Sie möglicherweise die Kommentare im Quellcode Ă€ndern. Um dies zu erleichtern, automatisiert der folgende Link diesen Vorgang.
Die Funktion ΔE2000 in C
Betrachten wir die gÀngigere und akademische (Sharma, 2005) der beiden Formulierungen.
// This function written in C 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.
#include <math.h>
// Expressly defining pi ensures that the code works on different platforms.
#ifndef M_PI
#define M_PI 3.14159265358979323846264338328
#endif
// 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.
static double ciede_2000(const double l_1, const double a_1, const double b_1, const double l_2, const double a_2, const double b_2) {
// Working in C 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 double k_l = 1.0;
const double k_c = 1.0;
const double k_h = 1.0;
double 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.
const double c_1 = sqrt(a_1 * a_1 * n * n + b_1 * b_1);
const double 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.
double h_1 = atan2(b_1, a_1 * n);
double h_2 = atan2(b_2, a_2 * n);
h_1 += (h_1 < 0.0) * 2.0 * M_PI;
h_2 += (h_2 < 0.0) * 2.0 * M_PI;
n = fabs(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.
double h_m = (h_1 + h_2) * 0.5;
double h_d = (h_2 - h_1) * 0.5;
h_d += (M_PI < n) * 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 < n) * M_PI;
// h_m += (M_PI < n) * ((h_m < M_PI) - (M_PI <= h_m)) * M_PI;
const double 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.
const double r_t = -2.0 * sqrt(n / (n + 6103515625.0))
* sin(M_PI / 3.0 * exp(p * p / (-25.0 * M_PI * M_PI)));
n = (l_1 + l_2) * 0.5;
n = (n - 50.0) * (n - 50.0);
// Lightness.
const double 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.
const double t = 1.0 + 0.24 * sin(2.0 * h_m + M_PI / 2.0)
+ 0.32 * sin(3.0 * h_m + 8.0 * M_PI / 15.0)
- 0.17 * sin(h_m + M_PI / 3.0)
- 0.20 * sin(4.0 * h_m + 3.0 * M_PI / 20.0);
n = c_1 + c_2;
// Hue.
const double h = 2.0 * sqrt(c_1 * c_2) * sin(h_d) / (k_h * (1.0 + 0.0075 * n * t));
// Chroma.
const double 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);
}
// Compilation is done using GCC or CLang :
// - gcc -std=c99 -Wall -Wextra -pedantic -Ofast -o ciede-2000-compiled ciede-2000.c -lm
// - clang -std=c99 -Wall -Wextra -pedantic -Ofast -o ciede-2000-compiled ciede-2000.c -lm
// GitHub Project : https://github.com/michel-leonard/ciede2000-color-matching
// Online Tests : https://michel-leonard.github.io/ciede2000-color-matching
// L1 = 65.4 a1 = 32.8 b1 = -3.5
// L2 = 64.1 a2 = 26.8 b2 = 4.2
// CIE ÎE00 = 5.5643553151 (Bruce Lindbloom, Netflixâs VMAF, ...)
// CIE ÎE00 = 5.5643412178 (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.Parameter k_l, k_c und k_h
Die k_l-, k_c- und k_h-Parameter in CIEDE2000 sind Gewichtungsfaktoren, die auf die Begriffe Helligkeit (ÎL*), Chroma (ÎC*) und Farbton (ÎH*) angewendet werden. Sie sind als Konstanten im Quellcode definiert. Ihr Standardwert ist 1, was den von der Internationalen Beleuchtungskommission (CIE) empfohlenen Standardbetrachtungsbedingungen entspricht. In der Praxis kann es erforderlich sein, diese Koeffizienten an spezifische Bedingungen anzupassen: So wird k_l = 2 manchmal verwendet, um Helligkeitsunterschiede stĂ€rker zu gewichten (was in der Textilindustrie hĂ€ufig vorkommt), wĂ€hrend k_c oder k_h je nach den Anforderungen reduziert werden können, um die Toleranz fĂŒr SĂ€ttigungs- oder Farbtonschwankungen zu erhöhen. Je nach Kontext liegen diese Koeffizienten normalerweise zwischen 0,5 und 2.
Genauigkeit und ZuverlÀssigkeit des Quellcodes
Der Unterschied zwischen der akademischen Formulierung von Sharma und der vereinfachten Formulierung von Lindbloom betrĂ€gt nicht mehr als ±0,0003 auf dem endgĂŒltigen ÎE2000. Dies entspricht dem Unterschied, der normalerweise zwischen zwei 32-Bit-Implementierungen gemessen wird und fĂŒr das menschliche Auge nicht wahrnehmbar ist. Unsere 64-Bit-Implementierungen, die alle miteinander ĂŒbereinstimmen, garantieren mindestens 10 korrekte Nachkommastellen, so dass die Wahl der einen Formulierung gegenĂŒber der anderen ein technisches Detail ist. Die Standardformel auf dieser Seite ist diejenige, die in der Community am hĂ€ufigsten verwendet wird, sie ist etwas einfacher zu vektorisieren.
â Wenn Sie einen Kommentar im Quellcode finden, der nicht mit einer anderen Sprache kompatibel ist, informieren Sie bitte den Autor der Seite, damit eine Korrektur vorgenommen werden kann.
Wie kann man RGB-Farben in L*a*b* umwandeln?
FĂŒr die Konvertierung mĂŒssen Sie den XYZ-Zwischenfarbraum verwenden. Falls Sie Hilfe benötigen, finden Sie den Quellcode am Ende dieser Seite (unter Verwendung des 1964 formalisierten D65-WeiĂpunkts).
Wertebereiche in CIELAB und Interpretation des ÎE2000
Im CIELAB-Farbraum steht die Komponente L* fĂŒr die Helligkeit und reicht normalerweise von 0 (schwarz) bis 100 (weiĂ). Die Komponenten a* und b* beschreiben die Farbachsen: a* verlĂ€uft von GrĂŒn nach Rot, b* von Blau nach Gelb. In der Praxis liegen a* und b* meist im Bereich von -128 bis +127, können aber je nach Farbumrechnung leicht darĂŒber hinausgehen.
| Farbe 1 | Farbe 2 | Wert des ÎE2000 |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
| Farbe 1 | Farbe 2 | Wert des ÎE2000 |
|---|---|---|
| 5 | ||
| 10 | ||
| 15 |
ÎE2000 (CIEDE2000) gibt den wahrgenommenen Unterschied zwischen zwei Farben an: 0 bedeutet identische Farben, höhere Werte (bis etwa 185 in extremen FĂ€llen) zeigen eine stĂ€rkere Abweichung. Beispielsweise entsprechen Werte um 5 eher Ă€hnlichen Farben, wĂ€hrend Werte um 15 deutlich unterschiedliche Farben anzeigen.
Anwendungsbeispiel in C
// Compute the Delta E (CIEDE2000) color difference between two L*a*b* colors in C99
const double l_1 = 28.9, a_1 = 47.5, b_1 = 2.0;
const double l_2 = 28.8, a_2 = 41.6, b_2 = -1.7;
const double delta_e = ciede_2000(l_1, a_1, b_1, l_2, a_2, b_2);
printf("%.12f\n", delta_e);
// .................................................. This shows a ΔE2000 of 2.7749016764
// As explained in the comments, compliance with Gaurav Sharma would display 2.7749152801Testergebnisse
Diese C-Funktion wurde mit dem für diesen Zweck entwickelten Julia-Multipräzisions-Treiber getestet.
CIEDE2000 Verification Summary :
First Verified Line : 48,104,115.93,93,27,56.7,40.47788983936747087
Duration : 18.26 s
Successes : 10000000
Errors : 0
Average Delta E : 62.9586
Average Deviation : 6.0772934018515914e-15
Maximum Deviation : 2.4158453015843406e-13Dateien zum Herunterladen
Verwenden Sie diese von Michel zur VerfĂŒgung gestellten Dateien frei, auch fĂŒr kommerzielle Zwecke.
| Datei | GröĂe | Anzahl der Klicks |
|---|---|---|
| ciede-2000.c | 4 KB | 111 |
| ciede-2000-driver.c | 47 KB | 139 |
| ciede-2000-random.c | 7 KB | 118 |
| ciede-2000-single-precision.c | 5 KB | 124 |
| compare-hex-colors.c | 11 KB | 112 |
| compare-rgb-colors.c | 11 KB | 120 |
| test-c.yml | 3 KB | 76 |
| vs-netflix.yml | 6 KB | 76 |
| reference-dataset.txt | 4 KB | 371 |
| Klicken Sie auf c.zip, um alle Dateien in einem Archiv herunterzuladen. | ||
Gemeinschaft
Was halten Sie von diesem Quellcode oder von CIEDE2000? Ihre Meinung ist uns wichtig! Das GÀstebuch enthÀlt bereits 9 EintrÀge - davon 1 auf Deutsch. Schauen Sie sich dort um und teilen Sie Ihre Meinung mit.