mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-08 16:48:29 +08:00
Merge pull request #35 from amueller/color_converters_dtype
ENH: Use dtype converters in color space manipulation.
This commit is contained in:
@@ -50,6 +50,7 @@ __docformat__ = "restructuredtext en"
|
||||
|
||||
import numpy as np
|
||||
from scipy import linalg
|
||||
from ..util import dtype
|
||||
|
||||
|
||||
def convert_colorspace(arr, fromspace, tospace):
|
||||
@@ -87,17 +88,17 @@ def convert_colorspace(arr, fromspace, tospace):
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> lena_hsv = convert_colorspace(lena, 'RGB', 'HSV')
|
||||
"""
|
||||
fromdict = {'RGB':lambda im: im, 'HSV':hsv2rgb, 'RGB CIE':rgbcie2rgb,
|
||||
'XYZ':xyz2rgb}
|
||||
todict = {'RGB':lambda im:im, 'HSV':rgb2hsv, 'RGB CIE':rgb2rgbcie,
|
||||
'XYZ':rgb2xyz}
|
||||
fromdict = {'RGB': lambda im: im, 'HSV': hsv2rgb, 'RGB CIE': rgbcie2rgb,
|
||||
'XYZ': xyz2rgb}
|
||||
todict = {'RGB': lambda im: im, 'HSV': rgb2hsv, 'RGB CIE': rgb2rgbcie,
|
||||
'XYZ': rgb2xyz}
|
||||
|
||||
fromspace = fromspace.upper()
|
||||
tospace = tospace.upper()
|
||||
if not fromspace in fromdict.keys():
|
||||
raise ValueError('fromspace needs to be one of %s'%fromdict.keys())
|
||||
raise ValueError('fromspace needs to be one of %s' % fromdict.keys())
|
||||
if not tospace in todict.keys():
|
||||
raise ValueError('tospace needs to be one of %s'%todict.keys())
|
||||
raise ValueError('tospace needs to be one of %s' % todict.keys())
|
||||
|
||||
return todict[tospace](fromdict[fromspace](arr))
|
||||
|
||||
@@ -133,7 +134,8 @@ def rgb2hsv(rgb):
|
||||
|
||||
Notes
|
||||
-----
|
||||
The conversion assumes an input data range of [0, 1] for all color components.
|
||||
The conversion assumes an input data range of [0, 1] for all
|
||||
color components.
|
||||
|
||||
Conversion between RGB and HSV color spaces results in some loss of
|
||||
precision, due to integer arithmetic and rounding [1]_.
|
||||
@@ -160,26 +162,26 @@ def rgb2hsv(rgb):
|
||||
# -- S channel
|
||||
delta = arr.ptp(-1)
|
||||
out_s = delta / out_v
|
||||
out_s[delta==0] = 0
|
||||
out_s[delta == 0] = 0
|
||||
|
||||
# -- H channel
|
||||
# red is max
|
||||
idx = (arr[:,:,0] == out_v)
|
||||
idx = (arr[:, :, 0] == out_v)
|
||||
out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx]
|
||||
|
||||
# green is max
|
||||
idx = (arr[:,:,1] == out_v)
|
||||
out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0] ) / delta[idx]
|
||||
idx = (arr[:, :, 1] == out_v)
|
||||
out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx]
|
||||
|
||||
# blue is max
|
||||
idx = (arr[:,:,2] == out_v)
|
||||
out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1] ) / delta[idx]
|
||||
out_h = (out[:,:,0] / 6.) % 1.
|
||||
idx = (arr[:, :, 2] == out_v)
|
||||
out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx]
|
||||
out_h = (out[:, :, 0] / 6.) % 1.
|
||||
|
||||
# -- output
|
||||
out[:,:,0] = out_h
|
||||
out[:,:,1] = out_s
|
||||
out[:,:,2] = out_v
|
||||
out[:, :, 0] = out_h
|
||||
out[:, :, 1] = out_s
|
||||
out[:, :, 2] = out_v
|
||||
|
||||
# remove NaN
|
||||
out[np.isnan(out)] = 0
|
||||
@@ -207,7 +209,8 @@ def hsv2rgb(hsv):
|
||||
|
||||
Notes
|
||||
-----
|
||||
The conversion assumes an input data range of [0, 1] for all color components.
|
||||
The conversion assumes an input data range of [0, 1] for all
|
||||
color components.
|
||||
|
||||
Conversion between RGB and HSV color spaces results in some loss of
|
||||
precision, due to integer arithmetic and rounding [1]_.
|
||||
@@ -228,12 +231,12 @@ def hsv2rgb(hsv):
|
||||
"""
|
||||
arr = _prepare_colorarray(hsv)
|
||||
|
||||
hi = np.floor(arr[:,:,0] * 6)
|
||||
f = arr[:,:,0] * 6 - hi
|
||||
p = arr[:,:,2] * (1 - arr[:,:,1])
|
||||
q = arr[:,:,2] * (1 - f * arr[:,:,1])
|
||||
t = arr[:,:,2] * (1 - (1 - f) * arr[:,:,1])
|
||||
v = arr[:,:,2]
|
||||
hi = np.floor(arr[:, :, 0] * 6)
|
||||
f = arr[:, :, 0] * 6 - hi
|
||||
p = arr[:, :, 2] * (1 - arr[:, :, 1])
|
||||
q = arr[:, :, 2] * (1 - f * arr[:, :, 1])
|
||||
t = arr[:, :, 2] * (1 - (1 - f) * arr[:, :, 1])
|
||||
v = arr[:, :, 2]
|
||||
|
||||
hi = np.dstack([hi, hi, hi]).astype(np.uint8) % 6
|
||||
out = np.choose(hi, [np.dstack((v, t, p)),
|
||||
@@ -250,14 +253,14 @@ def hsv2rgb(hsv):
|
||||
# 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
|
||||
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],
|
||||
xyz_from_rgb = np.array([[0.412453, 0.357580, 0.180423],
|
||||
[0.212671, 0.715160, 0.072169],
|
||||
[0.019334, 0.119193, 0.950227]])
|
||||
|
||||
@@ -284,6 +287,7 @@ grey_from_rgb = np.array([[0.2125, 0.7154, 0.0721],
|
||||
# The conversion functions that make use of the matrices above
|
||||
#-------------------------------------------------------------
|
||||
|
||||
|
||||
def _convert(matrix, arr):
|
||||
"""Do the color space conversion.
|
||||
|
||||
@@ -296,9 +300,10 @@ def _convert(matrix, arr):
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
out : ndarray, dtype=float
|
||||
The converted array.
|
||||
"""
|
||||
arr = dtype.img_as_float(arr)
|
||||
arr = _prepare_colorarray(arr)
|
||||
arr = np.swapaxes(arr, 0, 2)
|
||||
oldshape = arr.shape
|
||||
@@ -350,6 +355,7 @@ def xyz2rgb(xyz):
|
||||
"""
|
||||
return _convert(rgb_from_xyz, xyz)
|
||||
|
||||
|
||||
def rgb2xyz(rgb):
|
||||
"""RGB to XYZ color space conversion.
|
||||
|
||||
@@ -388,6 +394,7 @@ def rgb2xyz(rgb):
|
||||
"""
|
||||
return _convert(xyz_from_rgb, rgb)
|
||||
|
||||
|
||||
def rgb2rgbcie(rgb):
|
||||
"""RGB to RGB CIE color space conversion.
|
||||
|
||||
@@ -422,6 +429,7 @@ def rgb2rgbcie(rgb):
|
||||
"""
|
||||
return _convert(rgbcie_from_rgb, rgb)
|
||||
|
||||
|
||||
def rgbcie2rgb(rgbcie):
|
||||
"""RGB CIE to RGB color space conversion.
|
||||
|
||||
@@ -457,6 +465,7 @@ def rgbcie2rgb(rgbcie):
|
||||
"""
|
||||
return _convert(rgb_from_rgbcie, rgbcie)
|
||||
|
||||
|
||||
def rgb2grey(rgb):
|
||||
"""Compute luminance of an RGB image.
|
||||
|
||||
@@ -499,4 +508,3 @@ def rgb2grey(rgb):
|
||||
return _convert(grey_from_rgb, rgb)[..., 0]
|
||||
|
||||
rgb2gray = rgb2grey
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class TestColorconv(TestCase):
|
||||
|
||||
colbars = np.array([[1, 1, 0, 0, 1, 1, 0, 0],
|
||||
[1, 1, 1, 1, 0, 0, 0, 0],
|
||||
[1, 0, 1, 0, 1, 0, 1, 0]])
|
||||
[1, 0, 1, 0, 1, 0, 1, 0]]).astype(np.float)
|
||||
colbars_array = np.swapaxes(colbars.reshape(3, 4, 2), 0, 2)
|
||||
colbars_point75 = colbars * 0.75
|
||||
colbars_point75_array = np.swapaxes(colbars_point75.reshape(3, 4, 2), 0, 2)
|
||||
@@ -144,7 +144,7 @@ class TestColorconv(TestCase):
|
||||
'RGB', 'nokey')
|
||||
|
||||
def test_rgb2grey(self):
|
||||
x = np.array([1, 1, 1]).reshape((1, 1, 3))
|
||||
x = np.array([1, 1, 1]).reshape((1, 1, 3)).astype(np.float)
|
||||
g = rgb2grey(x)
|
||||
assert_array_almost_equal(g, 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user