Skip to content

Commit

Permalink
Simplify overflow handling of seed tolerance in flood_fill
Browse files Browse the repository at this point in the history
  • Loading branch information
lagru committed Feb 19, 2024
1 parent d1712b5 commit 2617ab1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
39 changes: 39 additions & 0 deletions skimage/_shared/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,42 @@ def numeric_dtype_min_max(dtype):
else:
raise ValueError(f"unsupported dtype {dtype!r}")
return min_, max_


def to_py_scalar(x):
"""Convert a NumPy scalar to the corresponding Python scalar.
Casts the given scalar to int, float, complex or bool depending on the
scalar dtype.
Parameters
----------
x : NumPy scalar
The scalar to convert.
Returns
-------
y : Python scalar
The corresponding Python scalar.
Examples
--------
>>> type(to_py_scalar(np.bool(True)))
<class 'bool'>
>>> type(to_py_scalar(np.uint8(3)))
<class 'int'>
>>> type(to_py_scalar(np.float64(3)))
<class 'float'>
>>> type(to_py_scalar(np.complex64(3j)))
<class 'complex'>
"""
if np.issubdtype(x, np.integer):
return int(x)
elif np.issubdtype(x, np.floating):
return float(x)
elif np.issubdtype(x, np.complexfloating):
return complex(x)
elif np.issubdtype(x, np.dtype(bool)):
return bool(x)
else:
raise ValueError(f"unsupported scalar type {type(x)}")
13 changes: 3 additions & 10 deletions skimage/morphology/_flood_fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
_resolve_neighborhood,
_set_border_values,
)
from .._shared.dtype import numeric_dtype_min_max
from .._shared.dtype import numeric_dtype_min_max, to_py_scalar


def flood_fill(
Expand Down Expand Up @@ -276,15 +276,8 @@ def flood(image, seed_point, *, footprint=None, connectivity=None, tolerance=Non
# Account for over- & underflow problems with seed_value ± tolerance
# in a way that works with NumPy 1 & 2
min_value, max_value = numeric_dtype_min_max(seed_value.dtype)
with np.errstate(over="raise", under="raise"):
try:
low_tol = max(min_value, seed_value - tolerance)
except (OverflowError, FloatingPointError):
low_tol = min_value
try:
high_tol = min(max_value, seed_value + tolerance)
except (OverflowError, FloatingPointError):
high_tol = max_value
low_tol = max(min_value, to_py_scalar(seed_value) - tolerance)
high_tol = min(max_value, to_py_scalar(seed_value) + tolerance)

_flood_fill_tolerance(
working_image.ravel(order),
Expand Down

0 comments on commit 2617ab1

Please sign in to comment.