2011-07-08 39 views
13

Tôi cần tính khoảng cách Delta-E giữa hai màu. Các thuật toán để làm như vậy với hai màu sắc trong không gian màu CIELAB trông như thế này:Có những thuật toán đã biết của thuật toán tính toán sai số màu CIEDE2000 hoặc CIE94 Delta-E không?

enter image description here

Có biết việc triển khai mã nguồn mở của thuật toán này? Nó không khó để thực hiện, nhưng từ nỗ lực cuối cùng của tôi trong việc thực hiện một thuật toán chuyển đổi không gian màu tôi không muốn tái phát triển bánh xe khi nó đã được trên đường và thử nghiệm.

CIEDE2000 sẽ đẹp hơn và chính xác hơn, nhưng cũng có thể quá mức trên iPhone. CIE94 sẽ ổn thôi.

+0

Không quan tâm: Thuật toán này (với các hằng số được chỉ định) miễn phí hoặc được cấp bằng sáng chế? Đó là những gì được gọi là? – Tim

+0

Tôi tin rằng đó là một tiêu chuẩn mở. Thông tin thêm: http://en.wikipedia.org/wiki/Color_difference và http://en.wikipedia.org/wiki/International_Commission_on_Illumination –

+0

Bạn có cần triển khai khoảng cách Delta-E hay chuyển đổi từ RGB sang CIELab đầy đủ? –

Trả lời

2

Tôi đã nhập phương trình (đối với mã Common Lisp xem ở dưới) và chạy một vài đánh giá ngẫu nhiên. Các thông số được liệt kê theo thứ tự này: L * 1 a * 1 b * 1 L * 2 a * 2 b * 2 DeltaE *

Tôi không chắc chắn rằng kết quả là chính xác. Nhưng nếu mã của bạn cung cấp cho kết quả tương tự, thì có thể là đủ.

((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)) 

Và đây là mã nguồn (thử nghiệm trong 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)) 
4

Có một mã nguồn mở C# thực hiện công thức CIE94 bạn cung cấp:

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

Nó yêu cầu màu sắc của bạn ở trong không gian màu LAB, nguồn chuyển đổi trong cùng một thư viện nếu cần.

Bạn cũng có thể check your cIE94 calculations online sử dụng cùng một thư viện.

Sau đây là đoạn có liên quan của mã, LABA và labB là đầu vào:

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); 

Các "hằng" được định nghĩa dựa trên loại ứng dụng của bạn:

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

[Phiên bản CIEDE2000] (https://github.com/THEjoezack/ColorMine/blob/master/ColorMine/ColorSpaces/Comparisons/CieDe2000Comparison.cs) từ cùng một thư viện – Warpling

0

Có một giấy có tên là " Công thức màu sắc khác biệt của CIEDE2000: Ghi chú thực hiện, dữ liệu thử nghiệm bổ sung và các quan sát toán học, "của Sharma et al. người đã đề xuất một số chỉnh sửa để xây dựng CIEDE2000 và bảng giá trị. Họ cũng đính kèm thực hiện cho MATLAB và MS Excel tại đây: http://www.ece.rochester.edu/~gsharma/ciede2000/

Bạn có thể dễ dàng tích hợp tệp excel trong dự án của mình để khôi phục kết quả hoặc nhận chức năng Matlab hoạt động trong môi trường C#. Nếu bạn không có MATLAB, bạn có thể dễ dàng có được Octave để làm điều đó cho bạn. Chỉ trong trường hợp có hướng dẫn sử dụng mã MATLAB trong các chương trình C# ở đây: http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c

+2

Chào mừng bạn đến [như vậy]. Bạn có thể muốn tóm tắt nội dung của liên kết đó. –

+0

Cập nhật với đề xuất của bạn. Hy vọng nó sẽ giúp tốt hơn bây giờ. –