diff --git a/skimage/io/tests/test_mpl_imshow.py b/skimage/io/tests/test_mpl_imshow.py index 9b814f57..e369273a 100644 --- a/skimage/io/tests/test_mpl_imshow.py +++ b/skimage/io/tests/test_mpl_imshow.py @@ -87,8 +87,7 @@ def test_outside_standard_range(): def test_nonstandard_type(): plt.figure() - with expected_warnings(["Non-standard image type", - "Low image dynamic range"]): + with expected_warnings(["Low image dynamic range"]): ax_im = io.imshow(im64) assert ax_im.get_clim() == (im64.min(), im64.max()) assert n_subplots(ax_im) == 2 diff --git a/skimage/util/dtype.py b/skimage/util/dtype.py index 1c594534..077b14be 100644 --- a/skimage/util/dtype.py +++ b/skimage/util/dtype.py @@ -21,8 +21,8 @@ dtype_range = {np.bool_: (False, True), integer_types = (np.uint8, np.uint16, np.int8, np.int16) _supported_types = (np.bool_, np.bool8, - np.uint8, np.uint16, np.uint32, - np.int8, np.int16, np.int32, + np.uint8, np.uint16, np.uint32, np.uint64, + np.int8, np.int16, np.int32, np.int64, np.float32, np.float64) if np.__version__ >= "1.6.0": @@ -125,7 +125,18 @@ def convert(image, dtype, force_copy=False, uniform=False): # Numbers can be represented exactly only if m is a multiple of n # Output array is of same kind as input. kind = a.dtype.kind - if n == m: + if n > m and a.max() < 2 ** m: + mnew = int(np.ceil(m / 2) * 2) + if mnew > m: + dtype = "int%s" % mnew + else: + dtype = "uint%s" % mnew + n = int(np.ceil(n / 2) * 2) + msg = ("Downcasting %s to %s without scaling because max " + "value %s fits in %s" % (a.dtype, dtype, a.max(), dtype)) + warn(msg) + return a.astype(_dtype2(kind, m)) + elif n == m: return a.copy() if copy else a elif n > m: # downscale with precision loss diff --git a/skimage/util/tests/test_dtype.py b/skimage/util/tests/test_dtype.py index 612c43e6..b8e77543 100644 --- a/skimage/util/tests/test_dtype.py +++ b/skimage/util/tests/test_dtype.py @@ -29,7 +29,7 @@ def test_range(): (img_as_float, np.float64), (img_as_uint, np.uint16), (img_as_ubyte, np.ubyte)]: - + with expected_warnings(['precision loss|sign loss|\A\Z']): y = f(x) @@ -62,7 +62,7 @@ def test_range_extra_dtypes(): for dtype_in, dt in dtype_pairs: imin, imax = dtype_range_extra[dtype_in] x = np.linspace(imin, imax, 10).astype(dtype_in) - + with expected_warnings(['precision loss|sign loss|\A\Z']): y = convert(x, dt) @@ -72,9 +72,12 @@ def test_range_extra_dtypes(): y, omin, omax, np.dtype(dt)) -def test_unsupported_dtype(): +def test_downcast(): x = np.arange(10).astype(np.uint64) - assert_raises(ValueError, img_as_int, x) + with expected_warnings('Downcasting'): + y = img_as_int(x) + assert np.allclose(y, x.astype(np.int16)) + assert y.dtype == np.int16, y.dtype def test_float_out_of_range():