vankappa
vankappa

Reputation: 81

imshow (Scikit Image) issue after thresholding

from skimage.io import imread, imshow
from skimage.filters import threshold_otsu

imgtest = imread('image.tif')


img_threshold = threshold_otsu(imgtest)
imshow(img_threshold)

returns

Traceback (most recent call last):
  File "<input>", line 8, in <module>
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_io.py", line 159, in imshow
    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/manage_plugins.py", line 209, in call_plugin
    return func(*args, **kwargs)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_plugins/matplotlib_plugin.py", line 158, in imshow
    ax_im = ax.imshow(image, **kwargs)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/matplotlib/__init__.py", line 1447, in inner
    return func(ax, *map(sanitize_sequence, args), **kwargs)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/matplotlib/axes/_axes.py", line 5523, in imshow
    im.set_data(X)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/matplotlib/image.py", line 711, in set_data
    raise TypeError("Invalid shape {} for image data"
TypeError: Invalid shape () for image data

and also

img_threshold2 = akt1 > 100
imshow(img_threshold2)

returns another error:

Traceback (most recent call last):
  File "<input>", line 2, in <module>
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_io.py", line 159, in imshow
    return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/manage_plugins.py", line 209, in call_plugin
    return func(*args, **kwargs)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_plugins/matplotlib_plugin.py", line 150, in imshow
    lo, hi, cmap = _get_display_range(image)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_plugins/matplotlib_plugin.py", line 97, in _get_display_range
    ip = _get_image_properties(image)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/io/_plugins/matplotlib_plugin.py", line 55, in _get_image_properties
    is_low_contrast(image))
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/skimage/exposure/exposure.py", line 637, in is_low_contrast
    limits = np.percentile(image, [lower_percentile, upper_percentile])
  File "<__array_function__ internals>", line 5, in percentile
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/numpy/lib/function_base.py", line 3818, in percentile
    return _quantile_unchecked(
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/numpy/lib/function_base.py", line 3937, in _quantile_unchecked
    r, k = _ureduce(a, func=_quantile_ureduce_func, q=q, axis=axis, out=out,
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/numpy/lib/function_base.py", line 3515, in _ureduce
    r = func(a, **kwargs)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/numpy/lib/function_base.py", line 4064, in _quantile_ureduce_func
    r = _lerp(x_below, x_above, weights_above, out=out)
  File "/Users/Simo/opt/anaconda3/envs/segmentation/lib/python3.8/site-packages/numpy/lib/function_base.py", line 3961, in _lerp
    diff_b_a = subtract(b, a)
TypeError: numpy boolean subtract, the `-` operator, is not supported, use the bitwise_xor, the `^` operator, or the logical_xor function instead.

as well.

I'm quite new to Python, so after reinstalling the packages mentioned in the errors (numpy, skimage) I exhausted my knowledge..

I'm using a conda environment & PyCharm, if it's useful to know.

Cheers

P.S. I'm on macOS Catalina

Upvotes: 0

Views: 1516

Answers (3)

gildniy
gildniy

Reputation: 3943

I think this answer can fix the problem, as it's what I used to handle it.

Upvotes: 1

Wt.N
Wt.N

Reputation: 1658

threshold_otsu expects an input image in grayscale, and it returns a threshould, a single scalar value. All pixels whose value >= threshold are assumed to be foreground.

import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage.filters import threshold_otsu

imgurl = 'https://i.picsum.photos/id/732/200/300.jpg?grayscale&hmac=ZeormnImNpZEXzeLNhI0BCcadwMVGAwJLPRh_Sl-7Wg'
img = imread(imgurl)  # Input image mast be grayscale
threshold = threshold_otsu(img)  # 132
binary = threshold <= img  # [[True True ...],..., [False True...]] 
# Pixel assumed to be forground where value >= threshould, otherwise background
imshow(binary)

# Btw, You can show images side by side by matplotlib.plt
import matplotlib.pyplot as plt
f, (ax0, ax1) = plt.subplots(1, 2)
ax0.imshow(img, cmap='gray')
ax1.imshow(binary, cmap='gray')
plt.show()  # attached below

Example image from https://picsum.photos/

Upvotes: 0

Sreeram TP
Sreeram TP

Reputation: 11937

threshold_otsu works properly on gray images.

I'm loading a color image and converting to gray for the example, if you already have gray image you can ignore that step.

from skimage.io import imread, imshow
from skimage.filters import threshold_otsu
from skimage.color import rgb2gray

imgtest = imread('00000001.jpg') # load my rgb image
gray = rgb2gray(imgtest) # convert to gray

img_threshold = threshold_otsu(gray) # apply thresholding
print(img_threshold) # 0.369140625 this is a number can't use imshow over this

binary = gray > img_threshold # converting to binary based on threshold -- this can be passed to imshow

imshow(binary) # image will be displayed now.!

Upvotes: 1

Related Questions