From 6585efb7634111911bebf55158e6f6f2b39b4c3e Mon Sep 17 00:00:00 2001 From: Matt Terry Date: Tue, 30 Jul 2013 14:20:55 -0700 Subject: [PATCH] lab2lch/lch2lab for N-D images (w/tests) --- skimage/color/colorconv.py | 25 ++++++++++++++++++++----- skimage/color/tests/test_colorconv.py | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index a09e8bdc..75f4eba2 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -1043,7 +1043,9 @@ def lab2lch(lab): Parameters ---------- lab : array_like - The image in CIE-LAB format, in a 3-D array of shape (.., .., 3). + The N-D image in CIE-LAB format. The last (`N+1`th) dimension must have + at least 3 elements, corresponding to the `L`, `a`, and `b` color + channels. Subsequent elements are copied. Returns ------- @@ -1070,13 +1072,13 @@ def lab2lch(lab): >>> lena_lab = rgb2lab(lena) >>> lena_lch = lab2lch(lena_lab) """ - lch = _prepare_colorarray(lab).copy() + lch = _prepare_lab_array(lab) a, b = lch[..., 1], lch[..., 2] lch[..., 1], lch[..., 2] = np.sqrt(a ** 2 + b ** 2), np.arctan2(b, a) H = lch[..., 2] - H[H < 0] += 2 * np.pi # (-pi, pi) -> (0, 2*pi) + H += np.where(H < 0, 2*np.pi, 0) # (-pi, pi) -> (0, 2*pi) return lch @@ -1088,7 +1090,9 @@ def lch2lab(lch): Parameters ---------- lab : array_like - The image in CIE-LCH format, in a 3-D array of shape (.., .., 3). + The N-D image in CIE-LCH format. The last (`N+1`th) dimension must have + at least 3 elements, corresponding to the `L`, `a`, and `b` color + channels. Subsequent elements are copied. Returns ------- @@ -1112,8 +1116,19 @@ def lch2lab(lch): >>> lena_lch = lab2lch(lena_lab) >>> lena_lab2 = lch2lab(lena_lch) """ - lch = _prepare_colorarray(lch).copy() + lch = _prepare_lab_array(lch) c, h = lch[..., 1], lch[..., 2] lch[..., 1], lch[..., 2] = c * np.cos(h), c * np.sin(h) return lch + + +def _prepare_lab_array(arr): + """Ensure input for lab2lch, lch2lab are well-posed. + + Arrays must be in floating point and have at least 3 elements in + last dimension. Return a new array. + """ + shape = arr.shape + assert shape[-1] >= 3 + return dtype.img_as_float(arr, force_copy=True) diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index f2e99095..fbec9ba6 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -264,6 +264,28 @@ class TestColorconv(TestCase): rgb2 = lab2rgb(lab2) assert_array_almost_equal(rgb, rgb2) + def test_lab_lch_0d(self): + lab0 = self._get_lab0() + lch0 = lab2lch(lab0) + lch2 = lab2lch(lab0[None, None, :]) + assert_array_almost_equal(lch0, lch2[0, 0, :]) + + def test_lab_lch_1d(self): + lab0 = self._get_lab0() + lch0 = lab2lch(lab0) + lch1 = lab2lch(lab0[None, :]) + assert_array_almost_equal(lch0, lch1[0, :]) + + def test_lab_lch_3d(self): + lab0 = self._get_lab0() + lch0 = lab2lch(lab0) + lch3 = lab2lch(lab0[None, None, None, :]) + assert_array_almost_equal(lch0, lch3[0, 0, 0, :]) + + def _get_lab0(self): + rgb = img_as_float(self.img_rgb[:1, :1, :]) + return rgb2lab(rgb)[0, 0, :] + def test_gray2rgb(): x = np.array([0, 0.5, 1])