From 95f18c71da002d5979da2290f37cc380bd5811c9 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Fri, 8 Aug 2014 10:43:57 +0200 Subject: [PATCH 01/10] Added support for different illuminants. --- skimage/__init__.py | 10 +-- skimage/color/colorconv.py | 163 +++++++++++++++++++++++++++++++------ 2 files changed, 144 insertions(+), 29 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index 59c80ed2..aacde5d6 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -65,11 +65,11 @@ from skimage._shared.utils import deprecated as _deprecated pkg_dir = _osp.abspath(_osp.dirname(__file__)) data_dir = _osp.join(pkg_dir, 'data') -try: - from .version import version as __version__ -except ImportError: - __version__ = "unbuilt-dev" -del version +# try: +# from .version import version as __version__ +# except ImportError: +# __version__ = "unbuilt-dev" +# del version try: diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 80f115ee..03fd8413 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -322,8 +322,86 @@ gray_from_rgb = np.array([[0.2125, 0.7154, 0.0721], [0, 0, 0]]) # CIE LAB constants for Observer= 2A, Illuminant= D65 +## NOTE: this is actually the XYZ values for the illuminant above. lab_ref_white = np.array([0.95047, 1., 1.08883]) +## XYZ coordinates of the illuminants, scaled to [0, 1]. For each illuminant I we have: +## +## illuminant[I][0] corresponds to the XYZ coordinates for the 2 degree +## field of view. +## +## illuminant[I][1] corresponds to the XYZ coordinates for the 10 degree +## field of view. +## +## The XYZ coordinates are calculated from [1], using the formula: +## +## X = x * ( Y / y ) +## Y = Y +## Z = ( 1 - x - y ) * ( Y / y ) +## +## where Y = 1. The only exception is the illuminant "D65" with aperture angle +## 2, whose coordinates are copied from 'lab_ref_white' for +## backward-compatibility reasons. +## +## References +## ---------- +## .. [1] http://en.wikipedia.org/wiki/Standard_illuminant + +illuminants = \ + {"A": [[1.098466069456375, 1, 0.3558228003436005], \ + [1.111420406956693, 1, 0.3519978321919493]], \ + "D50": [[0.9642119944211994, 1, 0.8251882845188288], \ + [0.9672062750333777, 1, 0.8142801513128616]], \ + "D55": [[0.956797052643698, 1, 0.9214805860173273], \ + [0.9579665682254781, 1, 0.9092525159847462]], \ + "D65": [lab_ref_white, \ + [0.94809667673716, 1, 1.0730513595166162]], \ + "D75": [[0.9497220898840717, 1, 1.226393520724154], \ + [0.9441713925645873, 1, 1.2064272211720228]], \ + "E": [[1.0, 1.0, 1.0], \ + [1.0, 1.0, 1.0]] + } + +def get_xyz_coords(illuminant, observer): + """Get the XYZ coordinates of the given illuminant and observer [1]. Currently + supported illuminants are: "A", "D50", "D55", "D65", "D75", "E". + + Parameters + ---------- + illuminant: string + The name of the illuminant (the function is NOT case sensitive). + observer: int + The aperture angle of the observer. + + Returns + ------- + xyz_coords: list + A list with 3 elements containing the XYZ coordinates of the given + illuminant. + + Raises + ------ + ValueError + If either the illuminant or the observer angle are not supported or + unknown. + + References + ---------- + .. [1] http://en.wikipedia.org/wiki/Standard_illuminant + + """ + illuminant = illuminant.upper() + if illuminant in illuminants.keys(): + if observer == 2: + idx = 0 + elif observer == 10: + idx = 10 + else: + ValueError("Unknown observer \"{}\"".format(observer)) + return illuminants[illuminant][idx] + else: + ValueError("Unknown illuminant \"{}\"".format(illuminant)) + # Haematoxylin-Eosin-DAB colorspace # From original Ruifrok's paper: A. C. Ruifrok and D. A. Johnston, @@ -666,9 +744,8 @@ def gray2rgb(image): return np.concatenate(3 * (image,), axis=-1) else: raise ValueError("Input image expected to be RGB, RGBA or gray.") - - -def xyz2lab(xyz): + +def xyz2lab(xyz, illuminant = "D65", observer = 2999999999): """XYZ to CIE-LAB color space conversion. Parameters @@ -676,6 +753,10 @@ def xyz2lab(xyz): xyz : array_like The image in XYZ format, in a 3- or 4-D array of shape ``(.., ..,[ ..,] 3)``. + illuminant: string + The name of the illuminant (the function is NOT case sensitive). + observer: int + The aperture angle of the observer. Returns ------- @@ -687,11 +768,15 @@ def xyz2lab(xyz): ------ ValueError If `xyz` is not a 3-D array of shape ``(.., ..,[ ..,] 3)``. + ValueError + If either the illuminant or the observer angle are not supported or + unknown. Notes ----- - Observer= 2A, Illuminant= D65 - CIE XYZ tristimulus values x_ref = 95.047, y_ref = 100., z_ref = 108.883 + By default Observer= 2A, Illuminant= D65. CIE XYZ tristimulus values x_ref + = 95.047, y_ref = 100., z_ref = 108.883. See function 'get_xyz_coords' for + a list of supported illuminants. References ---------- @@ -705,11 +790,14 @@ def xyz2lab(xyz): >>> lena = data.lena() >>> lena_xyz = rgb2xyz(lena) >>> lena_lab = xyz2lab(lena_xyz) + """ arr = _prepare_colorarray(xyz) + xyz_ref_white = get_xyz_coords(illuminant, observer) + # scale by CIE XYZ tristimulus values of the reference white point - arr = arr / lab_ref_white + arr = arr / xyz_ref_white # Nonlinear distortion and linear transformation mask = arr > 0.008856 @@ -725,14 +813,17 @@ def xyz2lab(xyz): return np.concatenate([x[..., np.newaxis] for x in [L, a, b]], axis=-1) - -def lab2xyz(lab): +def lab2xyz(lab, illuminant = "D65", observer = 2): """CIE-LAB to XYZcolor space conversion. Parameters ---------- lab : array_like The image in lab format, in a 3-D array of shape ``(.., .., 3)``. + illuminant: string + The name of the illuminant (the function is NOT case sensitive). + observer: int + The aperture angle of the observer. Returns ------- @@ -743,11 +834,16 @@ def lab2xyz(lab): ------ ValueError If `lab` is not a 3-D array of shape ``(.., .., 3)``. + ValueError + If either the illuminant or the observer angle are not supported or + unknown. + Notes ----- - Observer = 2A, Illuminant = D65 - CIE XYZ tristimulus values x_ref = 95.047, y_ref = 100., z_ref = 108.883 + By default Observer= 2A, Illuminant= D65. CIE XYZ tristimulus values x_ref + = 95.047, y_ref = 100., z_ref = 108.883. See function 'get_xyz_coords' for + a list of supported illuminants. References ---------- @@ -769,11 +865,11 @@ def lab2xyz(lab): out[mask] = np.power(out[mask], 3.) out[~mask] = (out[~mask] - 16.0 / 116.) / 7.787 - # rescale Observer= 2 deg, Illuminant= D65 - out *= lab_ref_white + # rescale to the reference white (illuminant) + xyz_ref_white = get_xyz_coords(illuminant, observer) + out *= xyz_ref_white return out - def rgb2lab(rgb): """RGB to lab color space conversion. @@ -826,7 +922,7 @@ def lab2rgb(lab): return xyz2rgb(lab2xyz(lab)) -def xyz2luv(xyz): +def xyz2luv(xyz, illuminant = "D65", observer = 2): """XYZ to CIE-Luv color space conversion. Parameters @@ -834,6 +930,10 @@ def xyz2luv(xyz): xyz : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in XYZ format. Final dimension denotes channels. + illuminant: string + The name of the illuminant (the function is NOT case sensitive). + observer: int + The aperture angle of the observer. Returns ------- @@ -844,11 +944,16 @@ def xyz2luv(xyz): ------ ValueError If `xyz` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``. + ValueError + If either the illuminant or the observer angle are not supported or + unknown. Notes ----- - XYZ conversion weights use Observer = 2A. Reference whitepoint for D65 - Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``. + By default XYZ conversion weights use Observer = 2A. Reference whitepoint + for D65 Illuminant, with XYZ tristimulus values of ``(95.047, 100., + 108.883)``. See function 'get_xyz_coords' for a list of supported + illuminants. References ---------- @@ -871,13 +976,14 @@ def xyz2luv(xyz): eps = np.finfo(np.float).eps # compute y_r and L - L = y / lab_ref_white[1] + xyz_ref_white = get_xyz_coords(illuminant, observer) + L = y / xyz_ref_white[1] mask = L > 0.008856 L[mask] = 116. * np.power(L[mask], 1. / 3.) - 16. L[~mask] = 903.3 * L[~mask] - u0 = 4*lab_ref_white[0] / np.dot([1, 15, 3], lab_ref_white) - v0 = 9*lab_ref_white[1] / np.dot([1, 15, 3], lab_ref_white) + u0 = 4*xyz_ref_white[0] / np.dot([1, 15, 3], xyz_ref_white) + v0 = 9*xyz_ref_white[1] / np.dot([1, 15, 3], xyz_ref_white) # u' and v' helper functions def fu(X, Y, Z): @@ -893,7 +999,7 @@ def xyz2luv(xyz): return np.concatenate([q[..., np.newaxis] for q in [L, u, v]], axis=-1) -def luv2xyz(luv): +def luv2xyz(luv, illuminant = "D65", observer = 2): """CIE-Luv to XYZ color space conversion. Parameters @@ -901,6 +1007,10 @@ def luv2xyz(luv): luv : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in CIE-Luv format. Final dimension denotes channels. + illuminant: string + The name of the illuminant (the function is NOT case sensitive). + observer: int + The aperture angle of the observer. Returns ------- @@ -911,11 +1021,15 @@ def luv2xyz(luv): ------ ValueError If `luv` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``. + ValueError + If either the illuminant or the observer angle are not supported or + unknown. Notes ----- XYZ conversion weights use Observer = 2A. Reference whitepoint for D65 - Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``. + Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``. See + function 'get_xyz_coords' for a list of supported illuminants. References ---------- @@ -935,12 +1049,13 @@ def luv2xyz(luv): mask = y > 7.999625 y[mask] = np.power((y[mask]+16.) / 116., 3.) y[~mask] = y[~mask] / 903.3 - y *= lab_ref_white[1] + xyz_ref_white = get_xyz_coords(illuminant, observer) + y *= xyz_ref_white[1] # reference white x,z uv_weights = [1, 15, 3] - u0 = 4*lab_ref_white[0] / np.dot(uv_weights, lab_ref_white) - v0 = 9*lab_ref_white[1] / np.dot(uv_weights, lab_ref_white) + u0 = 4*xyz_ref_white[0] / np.dot(uv_weights, xyz_ref_white) + v0 = 9*xyz_ref_white[1] / np.dot(uv_weights, xyz_ref_white) # compute intermediate values a = u0 + u / (13.*L + eps) From ba664df275007b34392becded4e4a5b73a8a752a Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Fri, 8 Aug 2014 13:28:45 +0200 Subject: [PATCH 02/10] Added new tests. The support for a wider range of illuminants is now tested. --- skimage/color/tests/data/lab_array_a_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d50_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d50_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d55_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d55_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d65_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d65_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d75_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_d75_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/lab_array_e_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_a_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d50_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d50_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d55_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d55_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d65_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d65_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d75_10.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_d75_2.npy | Bin 0 -> 200 bytes skimage/color/tests/data/luv_array_e_2.npy | Bin 0 -> 200 bytes 20 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 skimage/color/tests/data/lab_array_a_2.npy create mode 100644 skimage/color/tests/data/lab_array_d50_10.npy create mode 100644 skimage/color/tests/data/lab_array_d50_2.npy create mode 100644 skimage/color/tests/data/lab_array_d55_10.npy create mode 100644 skimage/color/tests/data/lab_array_d55_2.npy create mode 100644 skimage/color/tests/data/lab_array_d65_10.npy create mode 100644 skimage/color/tests/data/lab_array_d65_2.npy create mode 100644 skimage/color/tests/data/lab_array_d75_10.npy create mode 100644 skimage/color/tests/data/lab_array_d75_2.npy create mode 100644 skimage/color/tests/data/lab_array_e_2.npy create mode 100644 skimage/color/tests/data/luv_array_a_2.npy create mode 100644 skimage/color/tests/data/luv_array_d50_10.npy create mode 100644 skimage/color/tests/data/luv_array_d50_2.npy create mode 100644 skimage/color/tests/data/luv_array_d55_10.npy create mode 100644 skimage/color/tests/data/luv_array_d55_2.npy create mode 100644 skimage/color/tests/data/luv_array_d65_10.npy create mode 100644 skimage/color/tests/data/luv_array_d65_2.npy create mode 100644 skimage/color/tests/data/luv_array_d75_10.npy create mode 100644 skimage/color/tests/data/luv_array_d75_2.npy create mode 100644 skimage/color/tests/data/luv_array_e_2.npy diff --git a/skimage/color/tests/data/lab_array_a_2.npy b/skimage/color/tests/data/lab_array_a_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..cd1b81d1573f07d8e84f9b2e0367cbda6ddd4541 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm&2Ug!{^T^`#Z>9ILy59imL+yUJ&WP z)_2|RcDMO~V+U;P=1mVfkjDB!W4D@vgN*{`QgT|K7eqSz z)?VUzS)KiW*u(w&QIRGG(pW!e>{fGdcx}Tz^;Kf9Lli^xBD>4+2P$?T|8csgB_wba=iT^>hHjS7eqR+ zZ~n4eT!8t2g+Ns2@_6F|X{;YKcB?r!Jip}k{E4^-@!cGgPP-QghX T1H*^0UIz|oK3um!+sy$0d#pU! literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/lab_array_d55_10.npy b/skimage/color/tests/data/lab_array_d55_10.npy new file mode 100644 index 0000000000000000000000000000000000000000..566bc1105ba4f214ccec74a210bb9880a1115202 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm&2qL&DPP!gB|*Rd|&kEpT7eGUJ&V^ z)aSjg^4*vHy2~uRl22$HNMrq=v0Kf-VWNW6OqV&q4wveVsCT@HJy5Y@+F2`EcZd3$ T89)7%ybioSE5@s;_UI#dSJhb2B=k5Ri+;BaC literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/lab_array_d65_10.npy b/skimage/color/tests/data/lab_array_d65_10.npy new file mode 100644 index 0000000000000000000000000000000000000000..4ac9c0ae704ae50a63e8d508ca2e0664cdfd154e GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm%}2LIvXwN5QoZ`?w$jC0~{Fef=Gu6 zVfq)^e%-Q9U~vs-SpI&08tVs*-D(aFF?;)Cp4|?1xccb5qKa|!fr=f|&RWU3JLDz$ S=H?ypJRq1HyY<644+j93vOT*1 literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/lab_array_d65_2.npy b/skimage/color/tests/data/lab_array_d65_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..71e233d1bbfe0dac3cdbaa262ae264b5492f5bf6 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZmqW|D)VKfGLL5}?rOXsP7vR8v7eqQR zC^T;2=qa^ln4t6UQ9$edG}aFqyVV>V%wt2Or=1CQ=;*)G3nCpX zg!zBmzWdSsHS;}N&+AeSX{;YKcB?r!tk|-AO2yY;2bCvl7F)zb9;nzc?W~ooyTd2b TZ|%=!dmhL<(viF8rKbY`{{}z` literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/lab_array_d75_2.npy b/skimage/color/tests/data/lab_array_d75_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..1ef368552e9c96e9cae3654857e8ee8557b6b9e0 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZmqSwpKYKiHh(l9$QS3GUKnDiAAku;1 z_B{sWmV@?87SfKq0`d-NtRFOXt2sEF^+@x`y%_9JAN%jqD(T1r6+5P#wUTvrSZ*BP RV|K~&fLy6!T7!U>0{~7jHp>72 literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/lab_array_e_2.npy b/skimage/color/tests/data/lab_array_e_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..f795d3be3bd25be7f0da67611a8d79c26d04983a GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZmqXs`_jhdyf*g*$G2h6W7vR8v7eqSf zxKCQV_PD|UHAk1<&-ld;q_KX`*sbQ^Q1voE`rz~+hX%%sHn;GY0~I@_owbs6cc@jE S>2Q0M_kq*5`PG`_Jsbe$b38r( literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/luv_array_a_2.npy b/skimage/color/tests/data/luv_array_a_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..ae25c1194c05cba348092895621014365f3d6759 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm&3M2JG|0wB{*kWbqq_KX`*sbQ^p!iEI>*RBX1IAT`%?Z}Y2P$?G}aFqyVV>Ve#rV~nmy1skda!tH{@T!fr=f|&RWU3J8(@s Svt$Xs$AQ{OY626zJsbc%k3C}m literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/luv_array_d55_2.npy b/skimage/color/tests/data/luv_array_d55_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..88daa5db37c8ed97e8ff335b700fde08a08ae9bc GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm&5voe{Yxjr#e`#tLjM6wsl~@3nCr3 zgx)^qR#iMOedqCN4rPM_X{;YKcB?r!q&3dpx;#wdK-kGSQzSkm9H`ha?W~ooyMu3M T?&{oo?gz@>wcnUE(Zc}%)Tus* literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/luv_array_d65_10.npy b/skimage/color/tests/data/luv_array_d65_10.npy new file mode 100644 index 0000000000000000000000000000000000000000..43ce45abda121403c4d895528b7d954b6276a515 GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm%}G%({m0FQyqL_uKiLiadKe53nCpB z+-P>uJ3e#&_6xQ=u5*9xPhzRN@=ZO+ literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/luv_array_d65_2.npy b/skimage/color/tests/data/luv_array_d65_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..75ed4792d1f9c5554d16d33e232b2a6543247f5f GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZmqUdGL&c_tsSdZ2TYCf^I5{xj1(6O6 zZ@5yc^nL9QTw3O_zh&b7G}aFqyVV>VRL;ql?mnY*;1TCi-#ILfX%3-+T_LmF+#DG2f=CCo zXKg!PCW$#1`Tb>{*`n!?#`-~Hx0-{4#pP|w+v4O7Y%`qUa=tJAK*f$}XRT!29Zpz2 SyUQ}e<-k{-BR}%({T%=(H#~a) literal 0 HcmV?d00001 diff --git a/skimage/color/tests/data/luv_array_e_2.npy b/skimage/color/tests/data/luv_array_e_2.npy new file mode 100644 index 0000000000000000000000000000000000000000..f2f4c28044ef0231ba226495126dda9d52bbc27a GIT binary patch literal 200 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%IItqq53dWi`3bhIlz}3XeEOdUZm&1}tDf17WNO4fB*RP9Yb97+93nCrX zY!MQ;R%>uzdgE5( Date: Fri, 8 Aug 2014 14:22:27 +0200 Subject: [PATCH 03/10] Added tests for the new functionality. --- skimage/color/colorconv.py | 9 +++-- skimage/color/tests/test_colorconv.py | 58 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 03fd8413..46268bd2 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -392,15 +392,16 @@ def get_xyz_coords(illuminant, observer): """ illuminant = illuminant.upper() if illuminant in illuminants.keys(): + idx = 100; if observer == 2: idx = 0 elif observer == 10: - idx = 10 + idx = 1 else: - ValueError("Unknown observer \"{}\"".format(observer)) + raise ValueError("Unknown observer \"{}\"".format(observer)) return illuminants[illuminant][idx] else: - ValueError("Unknown illuminant \"{}\"".format(illuminant)) + raise ValueError("Unknown illuminant \"{}\"".format(illuminant)) # Haematoxylin-Eosin-DAB colorspace @@ -745,7 +746,7 @@ def gray2rgb(image): else: raise ValueError("Input image expected to be RGB, RGBA or gray.") -def xyz2lab(xyz, illuminant = "D65", observer = 2999999999): +def xyz2lab(xyz, illuminant = "D65", observer = 2): """XYZ to CIE-LAB color space conversion. Parameters diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index 63336a76..faf9b9db 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -233,10 +233,39 @@ class TestColorconv(TestCase): assert_array_almost_equal(xyz2lab(self.xyz_array), self.lab_array, decimal=3) + ## Thest the conversion with the rest of the illuminants. + for I in ["d50", "d55", "d65", "d75"]: + for obs in [2, 10]: + print("testing illuminant={}, observer={}".format(I, obs)) + fname = "lab_array_{}_{}.npy".format(I, obs) + lab_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(lab_array_I_obs, + xyz2lab(self.xyz_array, I, obs), decimal=2) + for I in ["a", "e"]: + print("testing illuminant={}, observer=2".format(I)) + fname = "lab_array_{}_2.npy".format(I) + lab_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(lab_array_I_obs, + xyz2lab(self.xyz_array, I, 2), decimal=2) + def test_lab2xyz(self): assert_array_almost_equal(lab2xyz(self.lab_array), self.xyz_array, decimal=3) + ## Thest the conversion with the rest of the illuminants. + for I in ["d50", "d55", "d65", "d75"]: + for obs in [2, 10]: + fname = "lab_array_{}_{}.npy".format(I, obs) + lab_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), + self.xyz_array, decimal=3) + for I in ["a", "e"]: + fname = "lab_array_{}_2.npy".format(I, obs) + lab_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, 2), + self.xyz_array, decimal=3) + + def test_rgb2lab_brucelindbloom(self): """ Test the RGB->Lab conversion by comparing to the calculator on the @@ -267,10 +296,39 @@ class TestColorconv(TestCase): assert_array_almost_equal(xyz2luv(self.xyz_array), self.luv_array, decimal=3) + ## Thest the conversion with the rest of the illuminants. + for I in ["d50", "d55", "d65", "d75"]: + for obs in [2, 10]: + print("testing illuminant={}, observer={}".format(I, obs)) + fname = "luv_array_{}_{}.npy".format(I, obs) + luv_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(luv_array_I_obs, + xyz2luv(self.xyz_array, I, obs), decimal=2) + for I in ["a", "e"]: + print("testing illuminant={}, observer=2".format(I)) + fname = "luv_array_{}_2.npy".format(I) + luv_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(luv_array_I_obs, + xyz2luv(self.xyz_array, I, 2), decimal=2) + + def test_luv2xyz(self): assert_array_almost_equal(luv2xyz(self.luv_array), self.xyz_array, decimal=3) + ## Thest the conversion with the rest of the illuminants. + for I in ["d50", "d55", "d65", "d75"]: + for obs in [2, 10]: + fname = "luv_array_{}_{}.npy".format(I, obs) + luv_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, obs), + self.xyz_array, decimal=3) + for I in ["a", "e"]: + fname = "luv_array_{}_2.npy".format(I, obs) + luv_array_I_obs = np.load(os.path.join('data', fname)) + assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, 2), + self.xyz_array, decimal=3) + def test_rgb2luv_brucelindbloom(self): """ Test the RGB->Lab conversion by comparing to the calculator on the From 118ce124bf11c58077f2e384664faca0f8072bd3 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Tue, 2 Sep 2014 08:01:22 +0200 Subject: [PATCH 04/10] Undone change in skimage/__init__.py. --- skimage/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index aacde5d6..59c80ed2 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -65,11 +65,11 @@ from skimage._shared.utils import deprecated as _deprecated pkg_dir = _osp.abspath(_osp.dirname(__file__)) data_dir = _osp.join(pkg_dir, 'data') -# try: -# from .version import version as __version__ -# except ImportError: -# __version__ = "unbuilt-dev" -# del version +try: + from .version import version as __version__ +except ImportError: + __version__ = "unbuilt-dev" +del version try: From ceae401d331a8942a43dc3b44dd0402a504aa3bf Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Tue, 2 Sep 2014 13:53:11 +0200 Subject: [PATCH 05/10] The format strings were updated to include numbers. --- skimage/color/tests/test_colorconv.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index faf9b9db..0c0fe507 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -236,14 +236,14 @@ class TestColorconv(TestCase): ## Thest the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: - print("testing illuminant={}, observer={}".format(I, obs)) - fname = "lab_array_{}_{}.npy".format(I, obs) + print("testing illuminant={0}, observer={1}".format(I, obs)) + fname = "lab_array_{0}_{1}.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(lab_array_I_obs, xyz2lab(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: - print("testing illuminant={}, observer=2".format(I)) - fname = "lab_array_{}_2.npy".format(I) + print("testing illuminant={0}, observer=2".format(I)) + fname = "lab_array_{0}_2.npy".format(I) lab_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(lab_array_I_obs, xyz2lab(self.xyz_array, I, 2), decimal=2) @@ -255,12 +255,12 @@ class TestColorconv(TestCase): ## Thest the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: - fname = "lab_array_{}_{}.npy".format(I, obs) + fname = "lab_array_{0}_{1}.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: - fname = "lab_array_{}_2.npy".format(I, obs) + fname = "lab_array_{0}_2.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, 2), self.xyz_array, decimal=3) @@ -299,14 +299,14 @@ class TestColorconv(TestCase): ## Thest the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: - print("testing illuminant={}, observer={}".format(I, obs)) - fname = "luv_array_{}_{}.npy".format(I, obs) + print("testing illuminant={0}, observer={1}".format(I, obs)) + fname = "luv_array_{0}_{1}.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(luv_array_I_obs, xyz2luv(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: - print("testing illuminant={}, observer=2".format(I)) - fname = "luv_array_{}_2.npy".format(I) + print("testing illuminant={0}, observer=2".format(I)) + fname = "luv_array_{0}_2.npy".format(I) luv_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(luv_array_I_obs, xyz2luv(self.xyz_array, I, 2), decimal=2) @@ -319,12 +319,12 @@ class TestColorconv(TestCase): ## Thest the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: - fname = "luv_array_{}_{}.npy".format(I, obs) + fname = "luv_array_{0}_{1}.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: - fname = "luv_array_{}_2.npy".format(I, obs) + fname = "luv_array_{0}_2.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join('data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, 2), self.xyz_array, decimal=3) From 4c3c49558d43f37c051e61f59e1480ac095497dd Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Wed, 3 Sep 2014 09:13:34 +0200 Subject: [PATCH 06/10] Corrected code to conform to Python coding conventions (PEP 8). Added test code for handling exceptions. Corrected test code to use the full path to the test data. --- skimage/__init__.py | 1 - skimage/color/colorconv.py | 74 +++++++++++++-------------- skimage/color/tests/test_colorconv.py | 39 +++++++++----- 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index 59c80ed2..b3f923db 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -71,7 +71,6 @@ except ImportError: __version__ = "unbuilt-dev" del version - try: _imp.find_module('nose') except ImportError: diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 46268bd2..69c95a8c 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -321,7 +321,7 @@ gray_from_rgb = np.array([[0.2125, 0.7154, 0.0721], [0, 0, 0], [0, 0, 0]]) -# CIE LAB constants for Observer= 2A, Illuminant= D65 +# CIE LAB constants for Observer=2A, Illuminant=D65 ## NOTE: this is actually the XYZ values for the illuminant above. lab_ref_white = np.array([0.95047, 1., 1.08883]) @@ -348,35 +348,35 @@ lab_ref_white = np.array([0.95047, 1., 1.08883]) ## .. [1] http://en.wikipedia.org/wiki/Standard_illuminant illuminants = \ - {"A": [[1.098466069456375, 1, 0.3558228003436005], \ - [1.111420406956693, 1, 0.3519978321919493]], \ - "D50": [[0.9642119944211994, 1, 0.8251882845188288], \ - [0.9672062750333777, 1, 0.8142801513128616]], \ - "D55": [[0.956797052643698, 1, 0.9214805860173273], \ - [0.9579665682254781, 1, 0.9092525159847462]], \ - "D65": [lab_ref_white, \ - [0.94809667673716, 1, 1.0730513595166162]], \ - "D75": [[0.9497220898840717, 1, 1.226393520724154], \ - [0.9441713925645873, 1, 1.2064272211720228]], \ - "E": [[1.0, 1.0, 1.0], \ - [1.0, 1.0, 1.0]] + {"A": [(1.098466069456375, 1, 0.3558228003436005), \ + (1.111420406956693, 1, 0.3519978321919493)], \ + "D50": [(0.9642119944211994, 1, 0.8251882845188288), \ + (0.9672062750333777, 1, 0.8142801513128616)], \ + "D55": [(0.956797052643698, 1, 0.9214805860173273), \ + (0.9579665682254781, 1, 0.9092525159847462)], \ + "D65": [(0.95047, 1., 1.08883), # This was: `lab_ref_white` + (0.94809667673716, 1, 1.0730513595166162)], \ + "D75": [(0.9497220898840717, 1, 1.226393520724154), \ + (0.9441713925645873, 1, 1.2064272211720228)], \ + "E": [(1.0, 1.0, 1.0), \ + (1.0, 1.0, 1.0)] } def get_xyz_coords(illuminant, observer): - """Get the XYZ coordinates of the given illuminant and observer [1]. Currently + """Get the XYZ coordinates of the given illuminant and observer [1]_. Currently supported illuminants are: "A", "D50", "D55", "D65", "D75", "E". Parameters ---------- - illuminant: string + illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer: int + observer : int, optional The aperture angle of the observer. Returns ------- - xyz_coords: list - A list with 3 elements containing the XYZ coordinates of the given + (x, y, z) : tuple + A tuple with 3 elements containing the XYZ coordinates of the given illuminant. Raises @@ -391,17 +391,17 @@ def get_xyz_coords(illuminant, observer): """ illuminant = illuminant.upper() - if illuminant in illuminants.keys(): + if illuminant in illuminants: idx = 100; if observer == 2: idx = 0 elif observer == 10: idx = 1 else: - raise ValueError("Unknown observer \"{}\"".format(observer)) + raise ValueError("Unknown observer \"{0}\"".format(observer)) return illuminants[illuminant][idx] else: - raise ValueError("Unknown illuminant \"{}\"".format(illuminant)) + raise ValueError("Unknown illuminant \"{0}\"".format(illuminant)) # Haematoxylin-Eosin-DAB colorspace @@ -746,7 +746,7 @@ def gray2rgb(image): else: raise ValueError("Input image expected to be RGB, RGBA or gray.") -def xyz2lab(xyz, illuminant = "D65", observer = 2): +def xyz2lab(xyz, illuminant="D65", observer=2): """XYZ to CIE-LAB color space conversion. Parameters @@ -754,9 +754,9 @@ def xyz2lab(xyz, illuminant = "D65", observer = 2): xyz : array_like The image in XYZ format, in a 3- or 4-D array of shape ``(.., ..,[ ..,] 3)``. - illuminant: string + illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer: int + observer : int, optional The aperture angle of the observer. Returns @@ -775,8 +775,8 @@ def xyz2lab(xyz, illuminant = "D65", observer = 2): Notes ----- - By default Observer= 2A, Illuminant= D65. CIE XYZ tristimulus values x_ref - = 95.047, y_ref = 100., z_ref = 108.883. See function 'get_xyz_coords' for + By default Observer= 2A, Illuminant= D65. CIE XYZ tristimulus values + x_ref=95.047, y_ref=100., z_ref=108.883. See function `get_xyz_coords` for a list of supported illuminants. References @@ -814,16 +814,16 @@ def xyz2lab(xyz, illuminant = "D65", observer = 2): return np.concatenate([x[..., np.newaxis] for x in [L, a, b]], axis=-1) -def lab2xyz(lab, illuminant = "D65", observer = 2): +def lab2xyz(lab, illuminant="D65", observer=2): """CIE-LAB to XYZcolor space conversion. Parameters ---------- lab : array_like The image in lab format, in a 3-D array of shape ``(.., .., 3)``. - illuminant: string + illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer: int + observer : int, optional The aperture angle of the observer. Returns @@ -923,7 +923,7 @@ def lab2rgb(lab): return xyz2rgb(lab2xyz(lab)) -def xyz2luv(xyz, illuminant = "D65", observer = 2): +def xyz2luv(xyz, illuminant="D65", observer=2): """XYZ to CIE-Luv color space conversion. Parameters @@ -931,9 +931,9 @@ def xyz2luv(xyz, illuminant = "D65", observer = 2): xyz : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in XYZ format. Final dimension denotes channels. - illuminant: string + illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer: int + observer : int, optional The aperture angle of the observer. Returns @@ -951,7 +951,7 @@ def xyz2luv(xyz, illuminant = "D65", observer = 2): Notes ----- - By default XYZ conversion weights use Observer = 2A. Reference whitepoint + By default XYZ conversion weights use observer=2A. Reference whitepoint for D65 Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``. See function 'get_xyz_coords' for a list of supported illuminants. @@ -1000,7 +1000,7 @@ def xyz2luv(xyz, illuminant = "D65", observer = 2): return np.concatenate([q[..., np.newaxis] for q in [L, u, v]], axis=-1) -def luv2xyz(luv, illuminant = "D65", observer = 2): +def luv2xyz(luv, illuminant="D65", observer=2): """CIE-Luv to XYZ color space conversion. Parameters @@ -1008,9 +1008,9 @@ def luv2xyz(luv, illuminant = "D65", observer = 2): luv : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in CIE-Luv format. Final dimension denotes channels. - illuminant: string + illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer: int + observer : int, optional The aperture angle of the observer. Returns @@ -1028,7 +1028,7 @@ def luv2xyz(luv, illuminant = "D65", observer = 2): Notes ----- - XYZ conversion weights use Observer = 2A. Reference whitepoint for D65 + XYZ conversion weights use observer=2A. Reference whitepoint for D65 Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``. See function 'get_xyz_coords' for a list of supported illuminants. diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index 0c0fe507..7a0f0afb 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -233,18 +233,18 @@ class TestColorconv(TestCase): assert_array_almost_equal(xyz2lab(self.xyz_array), self.lab_array, decimal=3) - ## Thest the conversion with the rest of the illuminants. + ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "lab_array_{0}_{1}.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join('data', fname)) + lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, xyz2lab(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: print("testing illuminant={0}, observer=2".format(I)) fname = "lab_array_{0}_2.npy".format(I) - lab_array_I_obs = np.load(os.path.join('data', fname)) + lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, xyz2lab(self.xyz_array, I, 2), decimal=2) @@ -252,19 +252,30 @@ class TestColorconv(TestCase): assert_array_almost_equal(lab2xyz(self.lab_array), self.xyz_array, decimal=3) - ## Thest the conversion with the rest of the illuminants. + ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: fname = "lab_array_{0}_{1}.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join('data', fname)) - assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), + lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: fname = "lab_array_{0}_2.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join('data', fname)) + lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, 2), self.xyz_array, decimal=3) - + + ## And we include a call to test the exception handling in the code. + try: + xs = lab2xyz(lab_array_I_obs, "NaI", 2) # Not an illuminant + except ValueError: + print 'Correctly handled the unknown illuminant case.' + + try: + xs = lab2xyz(lab_array_I_obs, "d50", 42) # Not an illuminant + except ValueError: + print 'Correctly handled the unknown observer case.' + def test_rgb2lab_brucelindbloom(self): """ @@ -296,18 +307,18 @@ class TestColorconv(TestCase): assert_array_almost_equal(xyz2luv(self.xyz_array), self.luv_array, decimal=3) - ## Thest the conversion with the rest of the illuminants. + ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "luv_array_{0}_{1}.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join('data', fname)) + luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, xyz2luv(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: print("testing illuminant={0}, observer=2".format(I)) fname = "luv_array_{0}_2.npy".format(I) - luv_array_I_obs = np.load(os.path.join('data', fname)) + luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, xyz2luv(self.xyz_array, I, 2), decimal=2) @@ -316,16 +327,16 @@ class TestColorconv(TestCase): assert_array_almost_equal(luv2xyz(self.luv_array), self.xyz_array, decimal=3) - ## Thest the conversion with the rest of the illuminants. + ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in [2, 10]: fname = "luv_array_{0}_{1}.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join('data', fname)) + luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: fname = "luv_array_{0}_2.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join('data', fname)) + luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, 2), self.xyz_array, decimal=3) From 272e9310d2bacc8b9a9534a28b421572c0bbd200 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Fri, 5 Sep 2014 13:35:35 +0200 Subject: [PATCH 07/10] Added Stephan comments. Syntax is now checked using `flake8`. --- skimage/__init__.py | 1 + skimage/color/colorconv.py | 147 +++++++++++++------------- skimage/color/tests/test_colorconv.py | 50 ++++----- 3 files changed, 100 insertions(+), 98 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index b3f923db..59c80ed2 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -71,6 +71,7 @@ except ImportError: __version__ = "unbuilt-dev" del version + try: _imp.find_module('nose') except ImportError: diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 69c95a8c..53642b1f 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -56,7 +56,7 @@ from __future__ import division import numpy as np from scipy import linalg from ..util import dtype -from skimage._shared.utils import deprecated +from skimage._shared.utils import deprecated # Imported but unused. Remove? def guess_spatial_dimensions(image): @@ -114,7 +114,8 @@ def convert_colorspace(arr, fromspace, tospace): Notes ----- Conversion occurs through the "central" RGB color space, i.e. conversion - from XYZ to HSV is implemented as ``XYZ -> RGB -> HSV`` instead of directly. + from XYZ to HSV is implemented as ``XYZ -> RGB -> HSV`` instead of + directly. Examples -------- @@ -129,9 +130,9 @@ def convert_colorspace(arr, fromspace, tospace): fromspace = fromspace.upper() tospace = tospace.upper() - if not fromspace in fromdict.keys(): + if fromspace not in fromdict.keys(): raise ValueError('fromspace needs to be one of %s' % fromdict.keys()) - if not tospace in todict.keys(): + if tospace not in todict.keys(): raise ValueError('tospace needs to be one of %s' % todict.keys()) return todict[tospace](fromdict[fromspace](arr)) @@ -287,15 +288,15 @@ def hsv2rgb(hsv): return out -#--------------------------------------------------------------- +# --------------------------------------------------------------- # Primaries for the coordinate systems -#--------------------------------------------------------------- +# --------------------------------------------------------------- cie_primaries = np.array([700, 546.1, 435.8]) sb_primaries = np.array([1. / 155, 1. / 190, 1. / 225]) * 1e5 -#--------------------------------------------------------------- +# --------------------------------------------------------------- # Matrices that define conversion between different color spaces -#--------------------------------------------------------------- +# --------------------------------------------------------------- # From sRGB specification xyz_from_rgb = np.array([[0.412453, 0.357580, 0.180423], @@ -322,49 +323,49 @@ gray_from_rgb = np.array([[0.2125, 0.7154, 0.0721], [0, 0, 0]]) # CIE LAB constants for Observer=2A, Illuminant=D65 -## NOTE: this is actually the XYZ values for the illuminant above. +# NOTE: this is actually the XYZ values for the illuminant above. lab_ref_white = np.array([0.95047, 1., 1.08883]) -## XYZ coordinates of the illuminants, scaled to [0, 1]. For each illuminant I we have: -## -## illuminant[I][0] corresponds to the XYZ coordinates for the 2 degree -## field of view. -## -## illuminant[I][1] corresponds to the XYZ coordinates for the 10 degree -## field of view. -## -## The XYZ coordinates are calculated from [1], using the formula: -## -## X = x * ( Y / y ) -## Y = Y -## Z = ( 1 - x - y ) * ( Y / y ) -## -## where Y = 1. The only exception is the illuminant "D65" with aperture angle -## 2, whose coordinates are copied from 'lab_ref_white' for -## backward-compatibility reasons. -## -## References -## ---------- -## .. [1] http://en.wikipedia.org/wiki/Standard_illuminant +# XYZ coordinates of the illuminants, scaled to [0, 1]. For each illuminant I +# we have: +# +# illuminant[I][0] corresponds to the XYZ coordinates for the 2 degree +# field of view. +# +# illuminant[I][1] corresponds to the XYZ coordinates for the 10 degree +# field of view. +# +# The XYZ coordinates are calculated from [1], using the formula: +# +# X = x * ( Y / y ) +# Y = Y +# Z = ( 1 - x - y ) * ( Y / y ) +# +# where Y = 1. The only exception is the illuminant "D65" with aperture angle +# 2, whose coordinates are copied from 'lab_ref_white' for +# backward-compatibility reasons. +# +# References +# ---------- +# .. [1] http://en.wikipedia.org/wiki/Standard_illuminant illuminants = \ - {"A": [(1.098466069456375, 1, 0.3558228003436005), \ - (1.111420406956693, 1, 0.3519978321919493)], \ - "D50": [(0.9642119944211994, 1, 0.8251882845188288), \ - (0.9672062750333777, 1, 0.8142801513128616)], \ - "D55": [(0.956797052643698, 1, 0.9214805860173273), \ - (0.9579665682254781, 1, 0.9092525159847462)], \ - "D65": [(0.95047, 1., 1.08883), # This was: `lab_ref_white` - (0.94809667673716, 1, 1.0730513595166162)], \ - "D75": [(0.9497220898840717, 1, 1.226393520724154), \ - (0.9441713925645873, 1, 1.2064272211720228)], \ - "E": [(1.0, 1.0, 1.0), \ - (1.0, 1.0, 1.0)] - } + {"A": {'2': (1.098466069456375, 1, 0.3558228003436005), + '10': (1.111420406956693, 1, 0.3519978321919493)}, + "D50": {'2': (0.9642119944211994, 1, 0.8251882845188288), + '10': (0.9672062750333777, 1, 0.8142801513128616)}, + "D55": {'2': (0.956797052643698, 1, 0.9214805860173273), + '10': (0.9579665682254781, 1, 0.9092525159847462)}, + "D65": {'2': (0.95047, 1., 1.08883), # This was: `lab_ref_white` + '10': (0.94809667673716, 1, 1.0730513595166162)}, + "D75": {'2': (0.9497220898840717, 1, 1.226393520724154), + '10': (0.9441713925645873, 1, 1.2064272211720228)}, + "E": {'2': (1.0, 1.0, 1.0), + '10': (1.0, 1.0, 1.0)}} + def get_xyz_coords(illuminant, observer): - """Get the XYZ coordinates of the given illuminant and observer [1]_. Currently - supported illuminants are: "A", "D50", "D55", "D65", "D75", "E". + """Get the XYZ coordinates of the given illuminant and observer [1]_. Parameters ---------- @@ -391,18 +392,11 @@ def get_xyz_coords(illuminant, observer): """ illuminant = illuminant.upper() - if illuminant in illuminants: - idx = 100; - if observer == 2: - idx = 0 - elif observer == 10: - idx = 1 - else: - raise ValueError("Unknown observer \"{0}\"".format(observer)) - return illuminants[illuminant][idx] - else: - raise ValueError("Unknown illuminant \"{0}\"".format(illuminant)) - + try: + return illuminants[illuminant][observer] + except KeyError: + raise ValueError("Unknown illuminant/observer combination\ + (\"{0}\", \"{1}\")".format(illuminant, observer)) # Haematoxylin-Eosin-DAB colorspace # From original Ruifrok's paper: A. C. Ruifrok and D. A. Johnston, @@ -487,9 +481,9 @@ rgb_from_hpx = np.array([[0.644211, 0.716556, 0.266844], rgb_from_hpx[2, :] = np.cross(rgb_from_hpx[0, :], rgb_from_hpx[1, :]) hpx_from_rgb = linalg.inv(rgb_from_hpx) -#------------------------------------------------------------- +# ------------------------------------------------------------- # The conversion functions that make use of the matrices above -#------------------------------------------------------------- +# ------------------------------------------------------------- def _convert(matrix, arr): @@ -745,8 +739,9 @@ def gray2rgb(image): return np.concatenate(3 * (image,), axis=-1) else: raise ValueError("Input image expected to be RGB, RGBA or gray.") - -def xyz2lab(xyz, illuminant="D65", observer=2): + + +def xyz2lab(xyz, illuminant="D65", observer="2"): """XYZ to CIE-LAB color space conversion. Parameters @@ -756,7 +751,7 @@ def xyz2lab(xyz, illuminant="D65", observer=2): ``(.., ..,[ ..,] 3)``. illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer : int, optional + observer : {"2", "10"}, optional The aperture angle of the observer. Returns @@ -796,7 +791,7 @@ def xyz2lab(xyz, illuminant="D65", observer=2): arr = _prepare_colorarray(xyz) xyz_ref_white = get_xyz_coords(illuminant, observer) - + # scale by CIE XYZ tristimulus values of the reference white point arr = arr / xyz_ref_white @@ -814,7 +809,8 @@ def xyz2lab(xyz, illuminant="D65", observer=2): return np.concatenate([x[..., np.newaxis] for x in [L, a, b]], axis=-1) -def lab2xyz(lab, illuminant="D65", observer=2): + +def lab2xyz(lab, illuminant="D65", observer="2"): """CIE-LAB to XYZcolor space conversion. Parameters @@ -823,7 +819,7 @@ def lab2xyz(lab, illuminant="D65", observer=2): The image in lab format, in a 3-D array of shape ``(.., .., 3)``. illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer : int, optional + observer : {"2", "10"}, optional The aperture angle of the observer. Returns @@ -871,6 +867,7 @@ def lab2xyz(lab, illuminant="D65", observer=2): out *= xyz_ref_white return out + def rgb2lab(rgb): """RGB to lab color space conversion. @@ -923,7 +920,7 @@ def lab2rgb(lab): return xyz2rgb(lab2xyz(lab)) -def xyz2luv(xyz, illuminant="D65", observer=2): +def xyz2luv(xyz, illuminant="D65", observer="2"): """XYZ to CIE-Luv color space conversion. Parameters @@ -933,7 +930,7 @@ def xyz2luv(xyz, illuminant="D65", observer=2): channels. illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer : int, optional + observer : {"2", "10"}, optional The aperture angle of the observer. Returns @@ -1000,7 +997,7 @@ def xyz2luv(xyz, illuminant="D65", observer=2): return np.concatenate([q[..., np.newaxis] for q in [L, u, v]], axis=-1) -def luv2xyz(luv, illuminant="D65", observer=2): +def luv2xyz(luv, illuminant="D65", observer="2"): """CIE-Luv to XYZ color space conversion. Parameters @@ -1010,7 +1007,7 @@ def luv2xyz(luv, illuminant="D65", observer=2): channels. illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional The name of the illuminant (the function is NOT case sensitive). - observer : int, optional + observer : {"2", "10"}, optional The aperture angle of the observer. Returns @@ -1164,7 +1161,8 @@ def hed2rgb(hed): Parameters ---------- hed : array_like - The image in the HED color space, in a 3-D array of shape ``(.., .., 3)``. + The image in the HED color space, in a 3-D array of shape + ``(.., .., 3)``. Returns ------- @@ -1207,7 +1205,8 @@ def separate_stains(rgb, conv_matrix): Returns ------- out : ndarray - The image in stain color space, in a 3-D array of shape ``(.., .., 3)``. + The image in stain color space, in a 3-D array of shape + ``(.., .., 3)``. Raises ------ @@ -1254,7 +1253,8 @@ def combine_stains(stains, conv_matrix): Parameters ---------- stains : array_like - The image in stain color space, in a 3-D array of shape ``(.., .., 3)``. + The image in stain color space, in a 3-D array of shape + ``(.., .., 3)``. conv_matrix: ndarray The stain separation matrix as described by G. Landini [1]_. @@ -1305,7 +1305,8 @@ def combine_stains(stains, conv_matrix): stains = dtype.img_as_float(stains) logrgb2 = np.dot(-np.reshape(stains, (-1, 3)), conv_matrix) rgb2 = np.exp(logrgb2) - return rescale_intensity(np.reshape(rgb2 - 2, stains.shape), in_range=(-1, 1)) + return rescale_intensity(np.reshape(rgb2 - 2, stains.shape), + in_range=(-1, 1)) def lab2lch(lab): diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index 7a0f0afb..cd591829 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -71,24 +71,24 @@ class TestColorconv(TestCase): colbars_point75 = colbars * 0.75 colbars_point75_array = np.swapaxes(colbars_point75.reshape(3, 4, 2), 0, 2) - xyz_array = np.array([[[0.4124, 0.21260, 0.01930]], # red - [[0, 0, 0]], # black - [[.9505, 1., 1.089]], # white - [[.1805, .0722, .9505]], # blue - [[.07719, .15438, .02573]], # green + xyz_array = np.array([[[0.4124, 0.21260, 0.01930]], # red + [[0, 0, 0]], # black + [[.9505, 1., 1.089]], # white + [[.1805, .0722, .9505]], # blue + [[.07719, .15438, .02573]], # green ]) - lab_array = np.array([[[53.233, 80.109, 67.220]], # red - [[0., 0., 0.]], # black - [[100.0, 0.005, -0.010]], # white - [[32.303, 79.197, -107.864]], # blue - [[46.229, -51.7, 49.898]], # green + lab_array = np.array([[[53.233, 80.109, 67.220]], # red + [[0., 0., 0.]], # black + [[100.0, 0.005, -0.010]], # white + [[32.303, 79.197, -107.864]], # blue + [[46.229, -51.7, 49.898]], # green ]) - luv_array = np.array([[[53.233, 175.053, 37.751]], # red - [[0., 0., 0.]], # black - [[100., 0.001, -0.017]], # white - [[32.303, -9.400, -130.358]], # blue - [[46.228, -43.774, 56.589]], # green + luv_array = np.array([[[53.233, 175.053, 37.751]], # red + [[0., 0., 0.]], # black + [[100., 0.001, -0.017]], # white + [[32.303, -9.400, -130.358]], # blue + [[46.228, -43.774, 56.589]], # green ]) # RGB to HSV @@ -235,7 +235,7 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: - for obs in [2, 10]: + for obs in ["2", "10"]: print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "lab_array_{0}_{1}.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) @@ -246,7 +246,7 @@ class TestColorconv(TestCase): fname = "lab_array_{0}_2.npy".format(I) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, - xyz2lab(self.xyz_array, I, 2), decimal=2) + xyz2lab(self.xyz_array, I, "2"), decimal=2) def test_lab2xyz(self): assert_array_almost_equal(lab2xyz(self.lab_array), @@ -254,7 +254,7 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: - for obs in [2, 10]: + for obs in ["2", "10"]: fname = "lab_array_{0}_{1}.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), @@ -262,17 +262,17 @@ class TestColorconv(TestCase): for I in ["a", "e"]: fname = "lab_array_{0}_2.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) - assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, 2), + assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, "2"), self.xyz_array, decimal=3) ## And we include a call to test the exception handling in the code. try: - xs = lab2xyz(lab_array_I_obs, "NaI", 2) # Not an illuminant + xs = lab2xyz(lab_array_I_obs, "NaI", "2") # Not an illuminant except ValueError: print 'Correctly handled the unknown illuminant case.' try: - xs = lab2xyz(lab_array_I_obs, "d50", 42) # Not an illuminant + xs = lab2xyz(lab_array_I_obs, "d50", "42") # Not an illuminant except ValueError: print 'Correctly handled the unknown observer case.' @@ -309,7 +309,7 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: - for obs in [2, 10]: + for obs in ["2", "10"]: print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "luv_array_{0}_{1}.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) @@ -320,7 +320,7 @@ class TestColorconv(TestCase): fname = "luv_array_{0}_2.npy".format(I) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, - xyz2luv(self.xyz_array, I, 2), decimal=2) + xyz2luv(self.xyz_array, I, "2"), decimal=2) def test_luv2xyz(self): @@ -329,7 +329,7 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: - for obs in [2, 10]: + for obs in ["2", "10"]: fname = "luv_array_{0}_{1}.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, obs), @@ -337,7 +337,7 @@ class TestColorconv(TestCase): for I in ["a", "e"]: fname = "luv_array_{0}_2.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) - assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, 2), + assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, "2"), self.xyz_array, decimal=3) def test_rgb2luv_brucelindbloom(self): From f078bcf779d205cdf12e44fcacf9c510a978d091 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Thu, 11 Sep 2014 11:09:27 +0200 Subject: [PATCH 08/10] Removed the print statements from the test code. --- skimage/__init__.py | 1 + skimage/color/tests/test_colorconv.py | 15 +++++---------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index 59c80ed2..8b5d4056 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -72,6 +72,7 @@ except ImportError: del version + try: _imp.find_module('nose') except ImportError: diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index cd591829..e9ac83ee 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -236,13 +236,11 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: - print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "lab_array_{0}_{1}.npy".format(I, obs) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, xyz2lab(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: - print("testing illuminant={0}, observer=2".format(I)) fname = "lab_array_{0}_2.npy".format(I) lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, @@ -267,15 +265,14 @@ class TestColorconv(TestCase): ## And we include a call to test the exception handling in the code. try: - xs = lab2xyz(lab_array_I_obs, "NaI", "2") # Not an illuminant + xs = lab2xyz(lab_array_I_obs, "NaI", "2") # Not an illuminant except ValueError: - print 'Correctly handled the unknown illuminant case.' - + pass + try: - xs = lab2xyz(lab_array_I_obs, "d50", "42") # Not an illuminant + xs = lab2xyz(lab_array_I_obs, "d50", "42") # Not an observer degree except ValueError: - print 'Correctly handled the unknown observer case.' - + pass def test_rgb2lab_brucelindbloom(self): """ @@ -310,13 +307,11 @@ class TestColorconv(TestCase): ## Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: - print("testing illuminant={0}, observer={1}".format(I, obs)) fname = "luv_array_{0}_{1}.npy".format(I, obs) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, xyz2luv(self.xyz_array, I, obs), decimal=2) for I in ["a", "e"]: - print("testing illuminant={0}, observer=2".format(I)) fname = "luv_array_{0}_2.npy".format(I) luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, From 27fcb81f74d42de0bc6761a632aaca2897cf8d16 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Thu, 11 Sep 2014 18:23:55 +0200 Subject: [PATCH 09/10] Incorporated Stefan's comments. --- skimage/__init__.py | 1 - skimage/color/colorconv.py | 5 +-- skimage/color/tests/test_colorconv.py | 60 ++++++++++++++++----------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/skimage/__init__.py b/skimage/__init__.py index 8b5d4056..59c80ed2 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -72,7 +72,6 @@ except ImportError: del version - try: _imp.find_module('nose') except ImportError: diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 53642b1f..e8a95db8 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -56,7 +56,6 @@ from __future__ import division import numpy as np from scipy import linalg from ..util import dtype -from skimage._shared.utils import deprecated # Imported but unused. Remove? def guess_spatial_dimensions(image): @@ -396,7 +395,7 @@ def get_xyz_coords(illuminant, observer): return illuminants[illuminant][observer] except KeyError: raise ValueError("Unknown illuminant/observer combination\ - (\"{0}\", \"{1}\")".format(illuminant, observer)) + (\'{0}\', \'{1}\')".format(illuminant, observer)) # Haematoxylin-Eosin-DAB colorspace # From original Ruifrok's paper: A. C. Ruifrok and D. A. Johnston, @@ -765,7 +764,7 @@ def xyz2lab(xyz, illuminant="D65", observer="2"): ValueError If `xyz` is not a 3-D array of shape ``(.., ..,[ ..,] 3)``. ValueError - If either the illuminant or the observer angle are not supported or + If either the illuminant or the observer angle is unsupported or unknown. Notes diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index e9ac83ee..cf960f4e 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -227,50 +227,57 @@ class TestColorconv(TestCase): def test_rgb2grey_on_grey(self): rgb2grey(np.random.rand(5, 5)) - # test matrices for xyz2lab and lab2xyz generated using http://www.easyrgb.com/index.php?X=CALC + # test matrices for xyz2lab and lab2xyz generated using + # http://www.easyrgb.com/index.php?X=CALC # Note: easyrgb website displays xyz*100 def test_xyz2lab(self): assert_array_almost_equal(xyz2lab(self.xyz_array), self.lab_array, decimal=3) - ## Test the conversion with the rest of the illuminants. + # Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: fname = "lab_array_{0}_{1}.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + lab_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, - xyz2lab(self.xyz_array, I, obs), decimal=2) + xyz2lab(self.xyz_array, I, obs), + decimal=2) for I in ["a", "e"]: fname = "lab_array_{0}_2.npy".format(I) - lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + lab_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab_array_I_obs, - xyz2lab(self.xyz_array, I, "2"), decimal=2) + xyz2lab(self.xyz_array, I, "2"), + decimal=2) def test_lab2xyz(self): assert_array_almost_equal(lab2xyz(self.lab_array), self.xyz_array, decimal=3) - ## Test the conversion with the rest of the illuminants. + # Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: fname = "lab_array_{0}_{1}.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) - assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), + lab_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) + assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: fname = "lab_array_{0}_2.npy".format(I, obs) - lab_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + lab_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(lab2xyz(lab_array_I_obs, I, "2"), - self.xyz_array, decimal=3) + self.xyz_array, decimal=3) - ## And we include a call to test the exception handling in the code. + # And we include a call to test the exception handling in the code. try: xs = lab2xyz(lab_array_I_obs, "NaI", "2") # Not an illuminant except ValueError: pass - + try: - xs = lab2xyz(lab_array_I_obs, "d50", "42") # Not an observer degree + xs = lab2xyz(lab_array_I_obs, "d50", "42") # Not a degree except ValueError: pass @@ -304,36 +311,41 @@ class TestColorconv(TestCase): assert_array_almost_equal(xyz2luv(self.xyz_array), self.luv_array, decimal=3) - ## Test the conversion with the rest of the illuminants. + # Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: fname = "luv_array_{0}_{1}.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + luv_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, - xyz2luv(self.xyz_array, I, obs), decimal=2) + xyz2luv(self.xyz_array, I, obs), + decimal=2) for I in ["a", "e"]: fname = "luv_array_{0}_2.npy".format(I) - luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + luv_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv_array_I_obs, - xyz2luv(self.xyz_array, I, "2"), decimal=2) - + xyz2luv(self.xyz_array, I, "2"), + decimal=2) def test_luv2xyz(self): assert_array_almost_equal(luv2xyz(self.luv_array), self.xyz_array, decimal=3) - ## Test the conversion with the rest of the illuminants. + # Test the conversion with the rest of the illuminants. for I in ["d50", "d55", "d65", "d75"]: for obs in ["2", "10"]: fname = "luv_array_{0}_{1}.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + luv_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, obs), self.xyz_array, decimal=3) for I in ["a", "e"]: fname = "luv_array_{0}_2.npy".format(I, obs) - luv_array_I_obs = np.load(os.path.join(os.path.dirname(__file__), 'data', fname)) + luv_array_I_obs = np.load( + os.path.join(os.path.dirname(__file__), 'data', fname)) assert_array_almost_equal(luv2xyz(luv_array_I_obs, I, "2"), - self.xyz_array, decimal=3) + self.xyz_array, decimal=3) def test_rgb2luv_brucelindbloom(self): """ From b44d4f7f456831639497ba1c3fd44adc2ea2c370 Mon Sep 17 00:00:00 2001 From: capitanbatata Date: Tue, 30 Sep 2014 08:32:48 +0200 Subject: [PATCH 10/10] Added Johannes' comments. --- skimage/color/colorconv.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index e8a95db8..47c5eac1 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -368,9 +368,9 @@ def get_xyz_coords(illuminant, observer): Parameters ---------- - illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional + illuminant : {"A", "D50", "D55", "D65", "D75", "E"}, optional The name of the illuminant (the function is NOT case sensitive). - observer : int, optional + observer : {"2", "10"}, optional The aperture angle of the observer. Returns @@ -748,7 +748,7 @@ def xyz2lab(xyz, illuminant="D65", observer="2"): xyz : array_like The image in XYZ format, in a 3- or 4-D array of shape ``(.., ..,[ ..,] 3)``. - illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional + illuminant : {"A", "D50", "D55", "D65", "D75", "E"}, optional The name of the illuminant (the function is NOT case sensitive). observer : {"2", "10"}, optional The aperture angle of the observer. @@ -816,7 +816,7 @@ def lab2xyz(lab, illuminant="D65", observer="2"): ---------- lab : array_like The image in lab format, in a 3-D array of shape ``(.., .., 3)``. - illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional + illuminant : {"A", "D50", "D55", "D65", "D75", "E"}, optional The name of the illuminant (the function is NOT case sensitive). observer : {"2", "10"}, optional The aperture angle of the observer. @@ -927,7 +927,7 @@ def xyz2luv(xyz, illuminant="D65", observer="2"): xyz : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in XYZ format. Final dimension denotes channels. - illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional + illuminant : {"A", "D50", "D55", "D65", "D75", "E"}, optional The name of the illuminant (the function is NOT case sensitive). observer : {"2", "10"}, optional The aperture angle of the observer. @@ -1004,7 +1004,7 @@ def luv2xyz(luv, illuminant="D65", observer="2"): luv : (M, N, [P,] 3) array_like The 3 or 4 dimensional image in CIE-Luv format. Final dimension denotes channels. - illuminant : {'A', 'D50', 'D55', 'D65', 'D75', 'E'}, optional + illuminant : {"A", "D50", "D55", "D65", "D75", "E"}, optional The name of the illuminant (the function is NOT case sensitive). observer : {"2", "10"}, optional The aperture angle of the observer.