Repository navigation
Closed
Milestone
Description
Description
There is a new problem with image inversion. As far as I can tell, it is not related to issue #3028 nor to PR #3030, as it concerns unsigned integer inversion. It is pretty enigmatic to me ... here it is:
In [1]: import numpy as np
In [2]: from skimage.util import invert
In [3]: imin = np.array([0, 1], np.uint64)
In [4]: imout = invert(imin)
In [5]: imtest = invert(imout)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-5-ab8c45624279> in <module>()
----> 1 imtest = invert(imout)
/Users/twalter/pycharm/scikit-image/skimage/util/_invert.pyc in invert(image, signed_float)
63 inverted = ~image
64 elif np.issubdtype(image.dtype, np.unsignedinteger):
---> 65 max_val = dtype_limits(image, clip_negative=False)[1]
66 inverted = max_val - image
67 elif np.issubdtype(image.dtype, np.signedinteger):
/Users/twalter/pycharm/scikit-image/skimage/util/dtype.pyc in dtype_limits(image, clip_negative)
48 warn('The default of `clip_negative` in `skimage.util.dtype_limits` '
49 'will change to `False` in version 0.15.')
---> 50 imin, imax = dtype_range[image.dtype.type]
51 if clip_negative:
52 imin = 0
KeyError: <type 'numpy.uint64'>
My observations:
- Among the unsigned integers, the problem only appears for
np.uint64. - It is a key error coming from
skimage.util.dtype_range. Indeed, we get the following:
In [7]: from skimage.util.dtype import dtype_range
In [8]: imin.dtype.type in dtype_range
Out[8]: True
In [9]: imout.dtype.type in dtype_range
Out[9]: False
- And this one I love:
In [10]: imin.dtype.type
Out[10]: numpy.uint64
In [11]: imout.dtype.type
Out[11]: numpy.uint64
In [12]: imin.dtype.type is imout.dtype.type
Out[12]: False
Way to reproduce
[If reporting a bug, please include the following important information:]
- Code example
- Relevant images (if any)
- Operating system and version: MacOS High Sierra, Version 10.13.3
- Python version:
Python 2.7.14 :: Anaconda custom (64-bit) - scikit-image version (run
skimage.__version__):0.14dev
Activity
soupault commentedon Apr 30, 2018
Sorry for the noise.
soupault commentedon Apr 30, 2018
OK, I think this is the cause:
Changing
inverted = max_val - imageto
inverted = image.dtype.type(max_val) - imagesolves the problem on my PC.
soupault commentedon Apr 30, 2018
Although, it seems that a part of the issue is on
numpyside.sciunto commentedon Apr 30, 2018
+1 @soupault Would you mind opening a ticket there?
soupault commentedon Apr 30, 2018
@sciunto sure, see numpy/numpy#11020.
eric-wieser commentedon Apr 30, 2018
This is a bug in scikit-image, although admittedly one we (numpy) led you into.
This returns false on all platforms
soupault commentedon May 1, 2018
I see:
I guess, a bugfix will be a bit more complex :).
@eric-wieser Could you point me at the definition code for [np.intc, np.intp, np.int_, np.longlong] and their unsigned analogues? It appears that some of these types are defined as aliases to the np.[u]int{32, ...}, while others are completely different objects (like np.uintp, in this case).
eric-wieser commentedon May 1, 2018
@soupault: The following list is all the unique integer types in numpy
np.bytenp.shortnp.intcnp.int_np.longlongnp.ubytenp.ushortnp.uintcnp.uintnp.ulonglongThese map directly to the underlying C types,
char,short,int,long,long long.Every other type is just an alias to one of these (ie,
np.t1 is np.t2).Unfortunately to make it more confusing, some of these types have the same
__name__- but this shouldn't matter in your implementation.The definition for these names is spread between the C code and python code. You can see a glimpse of the source in numpy/numpy#10151, which touches this file
jni commentedon May 1, 2018
Well this is nice and messy. On the plus side, as I've mentioned before, I don't think functions like
invertreally make sense foruint64orint64images — the max value is enormous! My suggested fix would be to catch the keyerror and issue a friendlier error message: "image inversion is only supported for the following dtypes:".eric-wieser commentedon May 1, 2018
@jni: That doesn't make any sense. You can't justify supporting
long(64 bits) but notlong long(64 bits) because "the max value is enormous" forlong long- clearly the same argument could be applied tolong.Also, on windows this manifests itself in 32-bit integers anyway (where
intandlongoverlap)soupault commentedon May 1, 2018
I agree :).
Ok, so basically,
np.XintYYabstraction is leaky, and we have to switch to the types above indtype_range. I'm taking a look if this would affect anything.soupault commentedon May 2, 2018
See #3050 for the fix.