scikit-image / scikit-image

Image processing in Python
https://scikit-image.org
Other
6.07k stars 2.22k forks source link

skimage.filters.threshold_triangle of empty image -> ValueError: attempt to get argmax of an empty sequence #7091

Closed petsuter closed 1 year ago

petsuter commented 1 year ago

Description:

Pass an uniform image to skimage.filters.threshold_triangle. This raises an exception with an unclear error message.

It should probably return the uniform value as the threshold, or raise an exception with a clearer error message.

threshold_isodata, threshold_li, threshold_local, threshold_mean, threshold_niblack, threshold_otsu, threshold_sauvola, threshold_yen have no problem with an empty / uniform image.

(threshold_minimum also fails: RuntimeError: Unable to find two maxima in histogram)

(threshold_multiotsu also fails: ValueError: After discretization into bins, the input image has only 1 different values. It cannot be thresholded in 3 classes. If there are more unique values before discretization, try increasing the number of bins (nbins).)

Way to reproduce:

from skimage.filters import threshold_triangle
threshold_triangle(numpy.zeros((10, 10), dtype='uint8'))
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    threshold_triangle(numpy.zeros((10, 10), dtype='uint8'))
  File "C:\Python311\Lib\site-packages\skimage\filters\thresholding.py", line 967, in threshold_triangle
    arg_level = np.argmax(length) + arg_low_level
  File "<__array_function__ internals>", line 200, in argmax
  File "C:\Python311\Lib\site-packages\numpy\core\fromnumeric.py", line 1242, in argmax
    return _wrapfunc(a, 'argmax', axis=axis, out=out, **kwds)
  File "C:\Python311\Lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
    return bound(*args, **kwds)
ValueError: attempt to get argmax of an empty sequence

Version information:

3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
scikit-image version: 0.21.0
numpy version: 1.24.3
decorouz commented 1 year ago

Hi @petsuter Thanks for reporting this. I can reproduce. Raising a ValueError if len(hist) < 2 or return the uniform value appears to be a fix. Do you agree?

petsuter commented 1 year ago

Hi @decorouz Thanks for reproducing. I agree returning the uniform value would be a useful fix, and also consistent with other thresholding methods in the same file. Example

Even better (but not strictly required to fix the bug) would be to reuse the same _validate_image_histogram helper and also add an optional hist input as in the other methods, which is more general and useful.

decorouz commented 1 year ago

Hi @petsuter Your suggestions are great. If you are feeling inspired and have time, you should create a PR for a fix. I think it would be appropriate to update test_triangle_uint_images too?