Question Existe-t-il des implémentations connues de l'algorithme de calcul de différence de couleur CIEDE2000 ou CIE94 Delta-E?


J'ai besoin de calculer la distance Delta-E entre deux couleurs. L'algorithme pour le faire avec deux couleurs dans l'espace colorimétrique CIELab ressemble à ceci:

enter image description here

Existe-t-il des implémentations open-source connues de cet algorithme? Ce n'est pas difficile à mettre en œuvre, mais depuis ma dernière tentative de mise en œuvre d'un algorithme de conversion de l'espace couleur, je préférerais ne pas re-développer la roue lorsqu'elle est déjà sur la route et testée.

CIEDE2000 serait bien aussi et plus précis, mais pourrait également être exagéré sur l’iPhone. CIE94 serait bien, je suppose.


13
2017-07-08 21:15


origine


Réponses:


J'ai tapé dans l'équation (pour le code Common Lisp voir en bas) et couru quelques évaluations aléatoires. Les paramètres sont répertoriés dans cet ordre: L * 1 a * 1 b * 1 L * 2 a * 2 b * 2 DeltaE *

Je ne suis pas parfaitement sûr que les résultats sont corrects. Mais si votre code donne les mêmes résultats, alors il est probablement suffisant.

   ((53.0 0.65 0.15 33.0 -0.45 -0.1 20.03112)
    (42.0 -0.3 0.1 74.0 -0.2 -0.15 32.001118)
    (12.0 -1.0 -0.45 32.0 0.3 0.9 20.084782)
    (94.0 -0.1 -0.55 77.0 0.5 0.45 17.03928)
    (75.0 -0.8 0.35 46.0 -0.6 -0.85 29.02483)
    (83.0 -0.65 -0.7 67.0 0.75 0.0 16.074173)
    (70.0 -0.7 0.9 54.0 0.35 -0.95 16.13608)
    (81.0 0.45 -0.8 53.0 -0.35 0.05 28.023375)
    (40.0 -0.2 -0.65 25.0 -1.0 0.8 15.088856)
    (66.0 0.85 -0.7 93.0 0.55 0.15 27.014244)
    (44.0 -0.5 0.5 23.0 -0.9 0.5 21.00363)
    (67.0 0.4 0.25 42.0 -0.25 0.6 25.010727)
    (32.0 0.6 0.55 86.0 0.0 0.25 54.003925)
    (96.0 -0.15 -0.9 87.0 0.25 -0.3 9.027307)
    (100.0 -0.6 0.3 61.0 -0.25 -0.75 39.015385)
    (2.0 -0.2 -0.65 73.0 -0.3 0.65 71.01173)
    (74.0 0.1 -0.65 96.0 -0.5 0.8 22.05474)
    (22.0 -0.3 -0.85 64.0 -0.65 -0.95 42.0015)
    (73.0 -0.35 0.3 38.0 0.25 -1.0 35.02875)
    (91.0 0.6 0.45 82.0 -0.25 0.2 9.042115))

Et voici le code source (testé dans SBCL):

;; http://en.wikipedia.org/wiki/Hypot thats not necessary if numbers
;; are not float and even if they are float the values of L*, a* and
;; b* are bound to tiny range
(defun hypot (x y)
  "Compute hypotenuse, prevent overflow."
  (declare (type number x y)
       (values number &optional))
  (let ((ax (abs x))
    (ay (abs y)))
    (if (or (< ax 1e-6) (< ay 1e-6))
    (sqrt (+ (* ax ax) (* ay ay)))
    (if (< ay ax)
        (* ax (sqrt (1+ (expt (/ y x) 2))))
        (* ay (sqrt (1+ (expt (/ x y) 2))))))))
#+nil
(list
 (hypot 1 0)
 (hypot 0 1)
 (hypot (sqrt 2) (sqrt 2))
 (hypot 2 10000))

;; http://www.devmaster.net/forums/archive/index.php/t-12680.html
(defun hypot3 (x y z)
  (hypot (hypot x y) z))

(defun delta-e*-94 (l1 a1 b1 l2 a2 b2 &key (application :graphic-arts))
  "Distance in CIE L* a* b* color space."
  (declare (type number l1 a1 b1 l2 a2 b2)
       (type (member :graphic-arts :textiles) application)
       (values number &optional))
  (destructuring-bind (kl k1 k2)
      (ecase application
    (:graphic-arts '(1 .045 .015))
    (:textiles '(2 .048 .014)))
   (let* ((delta-l (- l1 l2))
      (c1 (hypot a1 b1))
      (c2 (hypot a2 b2))
      (delta-c (- c1 c2))
      (delta-a (- a1 a2))
      (delta-b (- b1 b2))
      (delta-h (sqrt (+ (expt delta-a 2)
            (expt delta-b 2)
            (* -1 (expt delta-c 2)))))
      (l/k (/ delta-l kl))
      (c/k (/ delta-c (1+ (* k1 c1))))
      (h/k (/ delta-h (1+ (* k2 c1)))))
     (hypot3 l/k c/k h/k))))


#+nil ;; some test runs
(labels ((rL () ;; random number from 0..100 inclusive
       (random 101))
     (r- ()
       (/ (- (random 40) 20) 20))
     (r3 ()
       (list (rL) (r-) (r-))))
  (loop for i below 20 collect
   (destructuring-bind (l a b) (r3)
     (destructuring-bind (ll aa bb) (r3)
       (mapcar #'(lambda (x) (* 1s0 x)) 
           (list l a b ll aa bb (delta-e*-94 l a b ll aa bb))))))) 

#+nil ;; example test run
((80.0 0.85 0.35 13.0 0.4 -0.8 67.01107)
 (11.0 0.25 -0.35 66.0 0.45 0.15 55.002594)
 (74.0 -0.55 0.45 98.0 0.7 -0.85 24.066118)
 (37.0 -0.3 0.35 60.0 0.55 -0.3 23.02452)
 (20.0 -0.85 0.5 20.0 -0.25 0.1 0.6907073)
 (23.0 0.25 -0.05 15.0 0.55 -0.8 8.039892)
 (29.0 -0.55 0.05 9.0 -0.2 -0.8 20.020708)
 (11.0 0.55 -0.45 60.0 0.9 -0.15 49.00211)
 (70.0 0.5 -0.15 66.0 -0.8 0.85 4.3169336)
 (18.0 -0.5 0.55 49.0 0.5 -0.25 31.025839)
 (27.0 -0.95 0.3 43.0 -0.1 0.2 16.021187)
 (5.0 -0.4 0.5 70.0 -0.75 -0.75 65.012665)
 (9.0 -1.0 -0.2 66.0 0.4 0.05 57.01702)
 (10.0 0.25 -0.75 13.0 -0.85 -0.75 3.1900785)
 (16.0 -0.65 -0.4 31.0 -0.6 -0.5 15.000405)
 (90.0 0.4 0.1 18.0 -0.6 -0.85 72.01298)
 (92.0 0.4 0.1 31.0 -0.7 0.2 61.009853)
 (99.0 -0.7 -0.5 40.0 -0.9 0.35 59.006287)
 (40.0 0.95 -0.2 62.0 -0.7 -0.25 22.06002)
 (16.0 0.5 0.7 35.0 0.35 -0.45 19.03436))

2
2017-07-11 23:24



Il existe une implémentation C # open source de la formule CIE94 que vous avez fournie:

https://github.com/THEjoezack/ColorMine/blob/master/ColorMine/ColorSpaces/Comparisons/Cie94Comparison.cs

Il nécessite que vos couleurs soient dans l'espace colorimétrique LAB, dont la source de conversion se trouve dans la même bibliothèque si nécessaire.

Vous pouvez vérifiez vos calculs cIE94 en ligne en utilisant également la même bibliothèque.

Voici l'extrait pertinent de code, labA et labB sont les entrées:

var deltaL = labA.L - labB.L;
var deltaA = labA.A - labB.A;
var deltaB = labA.B - labB.B;

var c1 = Math.Sqrt(Math.Pow(labA.A, 2) + Math.Pow(labA.B, 2));
var c2 = Math.Sqrt(Math.Pow(labB.A, 2) + Math.Pow(labB.B, 2));
var deltaC = c1 - c2;

var deltaH = Math.Pow(deltaA,2) + Math.Pow(deltaB,2) - Math.Pow(deltaC,2);
deltaH = deltaH < 0 ? 0 : Math.Sqrt(deltaH);

const double sl = 1.0;
const double kc = 1.0;
const double kh = 1.0;

var sc = 1.0 + Constants.K1*c1;
var sh = 1.0 + Constants.K2*c1;

var i = Math.Pow(deltaL/(Constants.Kl*sl), 2) +
                Math.Pow(deltaC/(kc*sc), 2) +
                Math.Pow(deltaH/(kh*sh), 2);
var finalResult = i < 0 ? 0 : Math.Sqrt(i);

Les "constantes" sont définies en fonction de votre type d'application:

case Application.GraphicArts:
    Kl = 1.0;
    K1 = .045;
    K2 = .015;
    break;
case Application.Textiles:
    Kl = 2.0;
    K1 = .048;
    K2 = .014;
    break;

4
2017-08-24 02:43



Il existe un article intitulé "La formule de différence de couleur CIEDE2000: notes de mise en œuvre, données de test supplémentaires et observations mathématiques", par Sharma et al. qui a suggéré des corrections à la formulation CIEDE2000 et au tableau des valeurs. Ils ont également joint l'implémentation de MATLAB et MS Excel ici: http://www.ece.rochester.edu/~gsharma/ciede2000/

Vous pouvez facilement intégrer le fichier Excel dans votre projet pour récupérer les résultats ou obtenir que la fonction Matlab fonctionne sous un environnement C #. Si vous n'avez pas de matlab, vous pouvez facilement obtenir l'octave pour le faire pour vous. Juste au cas où il existe un manuel d'utilisation du code matlab dans les programmes C # ici: http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c


0
2018-01-27 09:39