From 28f58a2c504e908815f41fde0a952408553e646a Mon Sep 17 00:00:00 2001 From: Matt Terry Date: Mon, 22 Jul 2013 15:31:27 -0700 Subject: [PATCH] add tests. cmc stops naning --- skimage/color/__init__.py | 3 + skimage/color/delta_e.py | 27 ++-- skimage/color/tests/ciede2000_test_data.txt | 1 + skimage/color/tests/test_ciede2000.py | 61 -------- skimage/color/tests/test_dE.py | 145 ++++++++++++++++++++ 5 files changed, 161 insertions(+), 76 deletions(-) delete mode 100644 skimage/color/tests/test_ciede2000.py create mode 100644 skimage/color/tests/test_dE.py diff --git a/skimage/color/__init__.py b/skimage/color/__init__.py index 2d072808..95ccb0c0 100644 --- a/skimage/color/__init__.py +++ b/skimage/color/__init__.py @@ -96,5 +96,8 @@ __all__ = ['convert_colorspace', 'is_gray', 'color_dict', 'label2rgb', + 'deltaE_cie76', + 'deltaE_ciede94', 'deltaE_ciede2000', + 'deltaE_cmc', ] diff --git a/skimage/color/delta_e.py b/skimage/color/delta_e.py index 7c5399f6..47bf6e1a 100644 --- a/skimage/color/delta_e.py +++ b/skimage/color/delta_e.py @@ -112,10 +112,8 @@ def deltaE_ciede94(lab1, lab2, kH=1, kC=1, kL=1, k1=0.045, k2=0.015): dl = l1 - l2 c1 = np.sqrt(a1**2 + b1**2) c2 = np.sqrt(a2**2 + b2**2) - da = a1 - a2 - db = b1 - b2 dc = c1 - c2 - dh_ab = np.sqrt(da**2 + db**2 + dc**2) + dh_ab = np.sqrt(deltaE_cie76(lab1, lab2)**2 - dl**2 - dc**2) SL = 1 SC = 1 + k1*c1 @@ -186,11 +184,11 @@ def deltaE_ciede2000(lab1, lab2, kL=1, kC=1, kH=1): cc = c1_prime * c2_prime mask1 = cc == 0. - mask2 = (-mask1) * (dh_prime > np.pi) - mask3 = (-mask1) * (dh_prime < -np.pi) - dh_prime[mask1] = 0. - dh_prime[mask2] += 2*np.pi - dh_prime[mask3] -= 2*np.pi + mask2 = np.logical_and(-mask1, dh_prime > np.pi) + mask3 = np.logical_and(-mask1, dh_prime < -np.pi) + dh_prime = np.where(mask1, 0., dh_prime) + dh_prime += np.where(mask2, 2*np.pi, 0) + dh_prime -= np.where(mask3, 2*np.pi, 0) dH_prime = 2 * np.sqrt(cc) * np.sin(dh_prime/2) @@ -198,9 +196,10 @@ def deltaE_ciede2000(lab1, lab2, kL=1, kC=1, kH=1): mask0 = np.logical_and(np.abs(h1_prime - h2_prime) > np.pi, cc != 0.) mask1 = np.logical_and(mask0, Hbar_prime < 2*np.pi) mask2 = np.logical_and(mask0, Hbar_prime >= 2*np.pi) - Hbar_prime[mask1] += 2*np.pi - Hbar_prime[mask2] -= 2*np.pi - Hbar_prime[cc == 0.] *= 2 + + Hbar_prime += np.where(mask1, 2*np.pi, 0) + Hbar_prime -= np.where(mask2, 2*np.pi, 0) + Hbar_prime *= np.where(cc == 0., 2, 1) Hbar_prime *= 0.5 deg = np.pi/180. @@ -269,10 +268,8 @@ def deltaE_cmc(lab1, lab2, kL=1, kC=1): c1 = np.sqrt(a1**2 + b1**2) c2 = np.sqrt(a2**2 + b2**2) dC = c1 - c2 - - da = a1 - a2 - db = b1 - b2 - dH = np.sqrt(da**2 + db**2 - dC**2) + dl = l1 - l2 + dH = np.sqrt(deltaE_cie76(lab1, lab2)**2 - dl**2 - dC**2) dL = l1 - l2 diff --git a/skimage/color/tests/ciede2000_test_data.txt b/skimage/color/tests/ciede2000_test_data.txt index 28503ce5..b7e3fd57 100644 --- a/skimage/color/tests/ciede2000_test_data.txt +++ b/skimage/color/tests/ciede2000_test_data.txt @@ -1,5 +1,6 @@ # input, intermediate, and output values for CIEDE2000 dE function # data taken from "The CIEDE2000 Color-Difference Formula: Implementation Notes, ..." http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf +# tab delimited data # pair 1 L1 a1 b1 ap1 cp1 hp1 hbar1 G T SL SC SH RT dE 2 L2 a2 b2 ap2 cp2 hp2 1 1 50.0000 2.6772 -79.7751 2.6774 79.8200 271.9222 270.9611 0.0001 0.6907 1.0000 4.6578 1.8421 -1.7042 2.0425 2 50.0000 0.0000 -82.7485 0.0000 82.7485 270.0000 2 1 50.0000 3.1571 -77.2803 3.1573 77.3448 272.3395 271.1698 0.0001 0.6843 1.0000 4.6021 1.8216 -1.7070 2.8615 2 50.0000 0.0000 -82.7485 0.0000 82.7485 270.0000 diff --git a/skimage/color/tests/test_ciede2000.py b/skimage/color/tests/test_ciede2000.py deleted file mode 100644 index 5c00fb24..00000000 --- a/skimage/color/tests/test_ciede2000.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Test for correctness of color distance functions - -Authors -------- -Matt Terry - -:license: modified BSD -""" -from os.path import abspath, dirname, join as pjoin - -import numpy as np -from numpy.testing import assert_array_almost_equal - -from skimage.color import deltaE_ciede2000 - - -def test_ciede2000_dE(): - dtype = [('pair', int), - ('1', int), - ('L1', float), - ('a1', float), - ('b1', float), - ('a1_prime', float), - ('C1_prime', float), - ('h1_prime', float), - ('hbar_prime', float), - ('G', float), - ('T', float), - ('SL', float), - ('SC', float), - ('SH', float), - ('RT', float), - ('dE', float), - ('2', int), - ('L2', float), - ('a2', float), - ('b2', float), - ('a2_prime', float), - ('C2_prime', float), - ('h2_prime', float), - ] - - # note: ciede_test_data.txt contains several intermediate quantities - path = pjoin(dirname(abspath(__file__)), 'ciede_test_data.txt') - data = np.loadtxt(path, dtype=dtype) - - N = len(data) - - lab1 = np.zeros((N, 3)) - lab1[:, 0] = data['L1'] - lab1[:, 1] = data['a1'] - lab1[:, 2] = data['b1'] - - lab2 = np.zeros((N, 3)) - lab2[:, 0] = data['L2'] - lab2[:, 1] = data['a2'] - lab2[:, 2] = data['b2'] - - dE2 = deltaE_ciede2000(lab1, lab2) - - assert_array_almost_equal(dE2, data['dE']) diff --git a/skimage/color/tests/test_dE.py b/skimage/color/tests/test_dE.py new file mode 100644 index 00000000..04ad933b --- /dev/null +++ b/skimage/color/tests/test_dE.py @@ -0,0 +1,145 @@ +"""Test for correctness of color distance functions + +Authors +------- +Matt Terry + +:license: modified BSD +""" +from os.path import abspath, dirname, join as pjoin + +import numpy as np +from numpy.testing import assert_array_almost_equal + +from skimage.color import (deltaE_cie76, + deltaE_ciede94, + deltaE_ciede2000, + deltaE_cmc) + + +def test_ciede2000_dE(): + data = load_ciede2000_data() + N = len(data) + lab1 = np.zeros((N, 3)) + lab1[:, 0] = data['L1'] + lab1[:, 1] = data['a1'] + lab1[:, 2] = data['b1'] + + lab2 = np.zeros((N, 3)) + lab2[:, 0] = data['L2'] + lab2[:, 1] = data['a2'] + lab2[:, 2] = data['b2'] + + dE2 = deltaE_ciede2000(lab1, lab2) + + assert_array_almost_equal(dE2, data['dE']) + + +def load_ciede2000_data(): + dtype = [('pair', int), + ('1', int), + ('L1', float), + ('a1', float), + ('b1', float), + ('a1_prime', float), + ('C1_prime', float), + ('h1_prime', float), + ('hbar_prime', float), + ('G', float), + ('T', float), + ('SL', float), + ('SC', float), + ('SH', float), + ('RT', float), + ('dE', float), + ('2', int), + ('L2', float), + ('a2', float), + ('b2', float), + ('a2_prime', float), + ('C2_prime', float), + ('h2_prime', float), + ] + + # note: ciede_test_data.txt contains several intermediate quantities + path = pjoin(dirname(abspath(__file__)), 'ciede_test_data.txt') + return np.loadtxt(path, dtype=dtype) + + +def test_cie76(): + data = load_ciede2000_data() + N = len(data) + lab1 = np.zeros((N, 3)) + lab1[:, 0] = data['L1'] + lab1[:, 1] = data['a1'] + lab1[:, 2] = data['b1'] + + lab2 = np.zeros((N, 3)) + lab2[:, 0] = data['L2'] + lab2[:, 1] = data['a2'] + lab2[:, 2] = data['b2'] + + dE2 = deltaE_cie76(lab1, lab2) + oracle = np.array([ + 4.00106328, 6.31415011, 9.1776999, 2.06270077, 2.36957073, + 2.91529271, 2.23606798, 2.23606798, 4.98000036, 4.9800004, + 4.98000044, 4.98000049, 4.98000036, 4.9800004, 4.98000044, + 3.53553391, 36.86800781, 31.91002977, 30.25309901, 27.40894015, + 0.89242934, 0.7972, 0.8583065, 0.82982507, 3.1819238, + 2.21334297, 1.53890382, 4.60630929, 6.58467989, 3.88641412, + 1.50514845, 2.3237848, 0.94413208, 1.31910843 + ]) + assert_array_almost_equal(dE2, oracle) + + +def test_ciede94(): + data = load_ciede2000_data() + N = len(data) + lab1 = np.zeros((N, 3)) + lab1[:, 0] = data['L1'] + lab1[:, 1] = data['a1'] + lab1[:, 2] = data['b1'] + + lab2 = np.zeros((N, 3)) + lab2[:, 0] = data['L2'] + lab2[:, 1] = data['a2'] + lab2[:, 2] = data['b2'] + + dE2 = deltaE_ciede94(lab1, lab2) + oracle = np.array([ + 1.39503887, 1.93410055, 2.45433566, 0.68449187, 0.6695627, + 0.69194527, 2.23606798, 2.03163832, 4.80069441, 4.80069445, + 4.80069449, 4.80069453, 4.80069441, 4.80069445, 4.80069449, + 3.40774352, 34.6891632, 29.44137328, 27.91408781, 24.93766082, + 0.82213163, 0.71658427, 0.8048753, 0.75284394, 1.39099471, + 1.24808929, 1.29795787, 1.82045088, 2.55613309, 1.42491303, + 1.41945261, 2.3225685, 0.93853308, 1.30654464 + ]) + assert_array_almost_equal(dE2, oracle) + + +def test_cmc(): + data = load_ciede2000_data() + N = len(data) + lab1 = np.zeros((N, 3)) + lab1[:, 0] = data['L1'] + lab1[:, 1] = data['a1'] + lab1[:, 2] = data['b1'] + + lab2 = np.zeros((N, 3)) + lab2[:, 0] = data['L2'] + lab2[:, 1] = data['a2'] + lab2[:, 2] = data['b2'] + + dE2 = deltaE_cmc(lab1, lab2) + oracle = np.array([ + 1.73873611, 2.49660844, 3.30494501, 0.85735576, 0.88332927, + 0.97822692, 3.50480874, 2.87930032, 6.5783807, 6.57838075, + 6.5783808, 6.57838086, 6.67492321, 6.67492326, 6.67492331, + 4.66852997, 42.10875485, 39.45889064, 38.36005919, 33.93663807, + 1.14400168, 1.00600419, 1.11302547, 1.05335328, 1.42822951, + 1.2548143, 1.76838061, 2.02583367, 3.08695508, 1.74893533, + 1.90095165, 1.70258148, 1.80317207, 2.44934417 + ]) + + assert_array_almost_equal(dE2, oracle)