Skip to content

Commit

Permalink
Merge pull request scikit-image#3050 from soupault/dtype_range_and_in…
Browse files Browse the repository at this point in the history
…vert_bugfix

Switch to basis numpy int dtypes in dtype_range
  • Loading branch information
jni authored May 7, 2018
2 parents 16d3fd0 + 4c6de32 commit bbcdf93
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 17 deletions.
3 changes: 1 addition & 2 deletions skimage/measure/_structural_similarity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

from ..util.dtype import dtype_range
from ..util.arraycrop import crop
from .._shared.utils import deprecated
from .._shared.utils import skimage_deprecation, warn


__all__ = ['compare_ssim']

Expand Down
6 changes: 3 additions & 3 deletions skimage/util/_invert.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ def invert(image, signed_float=False):
inverted = ~image
elif np.issubdtype(image.dtype, np.unsignedinteger):
max_val = dtype_limits(image, clip_negative=False)[1]
inverted = max_val - image
inverted = np.subtract(max_val, image, dtype=image.dtype)
elif np.issubdtype(image.dtype, np.signedinteger):
inverted = -1 - image
inverted = np.subtract(-1, image, dtype=image.dtype)
else: # float dtype
if signed_float:
inverted = -image
else:
inverted = 1 - image
inverted = np.subtract(1, image, dtype=image.dtype)
return inverted
31 changes: 19 additions & 12 deletions skimage/util/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,35 @@
import numpy as np
from warnings import warn


__all__ = ['img_as_float32', 'img_as_float64', 'img_as_float',
'img_as_int', 'img_as_uint', 'img_as_ubyte',
'img_as_bool', 'dtype_limits']

# For integers Numpy uses `_integer_types` basis internally, and builds a leaky
# `np.XintYY` abstraction on top of it. This leads to situations when, for
# example, there are two np.Xint64 dtypes with the same attributes but
# different object references. In order to avoid any potential issues,
# we use the basis dtypes here. For more information, see:
# - https://github.com/scikit-image/scikit-image/issues/3043
# For convenience, for these dtypes we indicate also the possible bit depths
# (some of them are platform specific). For the details, see:
# http://www.unix.org/whitepapers/64bit.html
_integer_types = (np.byte, np.ubyte, # 8 bits
np.short, np.ushort, # 16 bits
np.intc, np.uintc, # 16 or 32 or 64 bits
np.int_, np.uint, # 32 or 64 bits
np.longlong, np.ulonglong) # 64 bits
_integer_ranges = {t: (np.iinfo(t).min, np.iinfo(t).max)
for t in _integer_types}
dtype_range = {np.bool_: (False, True),
np.bool8: (False, True),
np.uint8: (0, 255),
np.uint16: (0, 65535),
np.uint32: (0, 2**32 - 1),
np.uint64: (0, 2**64 - 1),
np.int8: (-128, 127),
np.int16: (-32768, 32767),
np.int32: (-2**31, 2**31 - 1),
np.int64: (-2**63, 2**63 - 1),
np.float16: (-1, 1),
np.float32: (-1, 1),
np.float64: (-1, 1)}
dtype_range.update(_integer_ranges)

_supported_types = (np.bool_, np.bool8,
np.uint8, np.uint16, np.uint32, np.uint64,
np.int8, np.int16, np.int32, np.int64,
np.float16, np.float32, np.float64)
_supported_types = list(dtype_range.keys())


def dtype_limits(image, clip_negative=None):
Expand Down
8 changes: 8 additions & 0 deletions skimage/util/tests/test_invert.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
from skimage import dtype_limits
from skimage.util.dtype import dtype_range
from skimage.util import invert

from skimage._shared.testing import assert_array_equal
Expand Down Expand Up @@ -67,3 +68,10 @@ def test_invert_float64_unsigned():
expected[1, :] = upper_dtype_limit
result = invert(image)
assert_array_equal(expected, result)


def test_invert_roundtrip():
for t, limits in dtype_range.items():
image = np.array(limits, dtype=t)
expected = invert(invert(image))
assert_array_equal(image, expected)

0 comments on commit bbcdf93

Please sign in to comment.