diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py index 38eab995..4186682d 100644 --- a/skimage/color/colorconv.py +++ b/skimage/color/colorconv.py @@ -79,7 +79,6 @@ def is_gray(image): return image.ndim == 2 - def convert_colorspace(arr, fromspace, tospace): """Convert an image array to a new color space. @@ -288,8 +287,8 @@ sb_primaries = np.array([1. / 155, 1. / 190, 1. / 225]) * 1e5 # From sRGB specification xyz_from_rgb = np.array([[0.412453, 0.357580, 0.180423], - [0.212671, 0.715160, 0.072169], - [0.019334, 0.119193, 0.950227]]) + [0.212671, 0.715160, 0.072169], + [0.019334, 0.119193, 0.950227]]) rgb_from_xyz = linalg.inv(xyz_from_rgb) @@ -379,7 +378,13 @@ def xyz2rgb(xyz): >>> lena_xyz = rgb2xyz(lena) >>> lena_rgb = xyz2rgb(lena_xyz) """ - return _convert(rgb_from_xyz, xyz) + # Follow the algorithm from http://www.easyrgb.com/index.php + # except we don't multiply/divide by 100 in the conversion + arr = _convert(rgb_from_xyz, xyz) + mask = arr > 0.0031308 + arr[mask] = 1.055 * np.power(arr[mask], 1 / 2.4) - 0.055 + arr[~mask] *= 12.92 + return arr def rgb2xyz(rgb): @@ -415,7 +420,13 @@ def rgb2xyz(rgb): >>> lena = data.lena() >>> lena_xyz = rgb2xyz(lena) """ - return _convert(xyz_from_rgb, rgb) + # Follow the algorithm from http://www.easyrgb.com/index.php + # except we don't multiply/divide by 100 in the conversion + arr = _prepare_colorarray(rgb).copy() + mask = arr > 0.04045 + arr[mask] = np.power((arr[mask] + 0.055) / 1.055, 2.4) + arr[~mask] /= 12.92 + return _convert(xyz_from_rgb, arr) def rgb2rgbcie(rgb): diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index c09c9d22..962fa9fc 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -113,10 +113,14 @@ class TestColorconv(TestCase): # XYZ to RGB def test_xyz2rgb_conversion(self): - # only roundtrip test, we checked rgb2xyz above already assert_almost_equal(xyz2rgb(rgb2xyz(self.colbars_array)), self.colbars_array) + # RGB<->XYZ roundtrip on another image + def test_xyz_rgb_roundtrip(self): + img_rgb = img_as_float(self.img_rgb) + assert_array_almost_equal(xyz2rgb(rgb2xyz(img_rgb)), img_rgb) + # RGB to RGB CIE def test_rgb2rgbcie_conversion(self): gt = np.array([[[ 0.1488856 , 0.18288098, 0.19277574], @@ -175,11 +179,29 @@ class TestColorconv(TestCase): assert_array_almost_equal(lab2xyz(self.lab_array), self.xyz_array, decimal=3) + def test_rgb2lab_brucelindbloom(self): + """ + Test the RGB->Lab conversion by comparing to the calculator on the + authoritative Bruce Lindbloom + [website](http://brucelindbloom.com/index.html?ColorCalculator.html). + """ + # Obtained with D65 white point, sRGB model and gamma + gt_for_colbars = np.array([ + [100,0,0], + [97.1393, -21.5537, 94.4780], + [91.1132, -48.0875, -14.1312], + [87.7347, -86.1827, 83.1793], + [60.3242, 98.2343, -60.8249], + [53.2408, 80.0925, 67.2032], + [32.2970, 79.1875, -107.8602], + [0,0,0]]).T + gt_array = np.swapaxes(gt_for_colbars.reshape(3, 4, 2), 0, 2) + assert_array_almost_equal(rgb2lab(self.colbars_array), gt_array, decimal=2) + def test_lab_rgb_roundtrip(self): img_rgb = img_as_float(self.img_rgb) assert_array_almost_equal(lab2rgb(rgb2lab(img_rgb)), img_rgb) - def test_gray2rgb(): x = np.array([0, 0.5, 1]) assert_raises(ValueError, gray2rgb, x) diff --git a/skimage/segmentation/tests/test_quickshift.py b/skimage/segmentation/tests/test_quickshift.py index d43d7559..a940f859 100644 --- a/skimage/segmentation/tests/test_quickshift.py +++ b/skimage/segmentation/tests/test_quickshift.py @@ -34,10 +34,10 @@ def test_color(): seg = quickshift(img, random_seed=0, max_dist=30, kernel_size=10, sigma=0) # we expect 4 segments: assert_equal(len(np.unique(seg)), 4) - assert_array_equal(seg[:10, :10], 0) - assert_array_equal(seg[10:, :10], 3) - assert_array_equal(seg[:10, 10:], 1) - assert_array_equal(seg[10:, 10:], 2) + assert_array_equal(seg[:10, :10], 1) + assert_array_equal(seg[10:, :10], 2) + assert_array_equal(seg[:10, 10:], 0) + assert_array_equal(seg[10:, 10:], 3) seg2 = quickshift(img, kernel_size=1, max_dist=2, random_seed=0, convert2lab=False, sigma=0)