Merge pull request #1818 from blink1073/improve_downcast

Add support for casting from 64bit integers and use smart downcast
This commit is contained in:
Juan Nunez-Iglesias
2015-12-13 10:54:39 +11:00
3 changed files with 22 additions and 9 deletions
+1 -2
View File
@@ -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
+14 -3
View File
@@ -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
+7 -4
View File
@@ -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():