Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a port of scipy.ndimage.measurement.watershed. #99

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions dask_image/ndmeasure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,3 +649,97 @@ def variance(input, labels=None, index=None):
)

return var_lbl

# this version of a watershed alg. is adapted from scipy.ndimage.measurement
def watershed_ift(input, markers, structure=None, output=None):
"""
Apply watershed from markers using image foresting transform algorithm.

Parameters
----------
input : array_like
Input.
markers : array_like
Markers are points within each watershed that form the beginning
of the process. Negative markers are considered background markers
which are processed after the other markers.
structure : structure element, optional
A structuring element defining the connectivity of the object can be
provided. If None, an element is generated with a squared
connectivity equal to one.
output : ndarray, optional
An output array can optionally be provided. The same shape as input.

Returns
-------
watershed_ift : ndarray
Output. Same shape as `input`.

References
----------
.. [1] A.X. Falcao, J. Stolfi and R. de Alencar Lotufo, "The image
foresting transform: theory, algorithms, and applications",
Pattern Analysis and Machine Intelligence, vol. 26, pp. 19-29, 2004.

"""
print("Warning: watershed is a stub")
warn("Warning: watershed is a stub", RuntimeWarning)

input = dask.array.asarray(input)

if input.dtype.type not in [numpy.uint8, numpy.uint16]:
raise TypeError('only 8 and 16 unsigned inputs are supported')

if not all([len(c) == 1 for c in input.chunks]):
warn("``input`` does not have 1 chunk in all dimensions; it will be consolidated first", RuntimeWarning)

if structure is None:
structure = scipy.ndimage.generate_binary_structure(input.ndim, 1)
structure = dask.array.asarray(structure, dtype=bool)
if structure.ndim != input.ndim:
raise RuntimeError('structure and input must have equal rank')
for ii in structure.shape:
if ii != 3:
raise RuntimeError('structure dimensions must be equal to 3')

return None #
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably still too early for comments on this yet, but I wanted to flag that the indentation level here suggests that this function must return None every time. I imagine that's not quite what's intended, unless I'm missing context.

#input = numpy.asarray(input)
#if input.dtype.type not in [numpy.uint8, numpy.uint16]:
# raise TypeError('only 8 and 16 unsigned inputs are supported')

if structure is None:
structure = scipy.ndimage.generate_binary_structure(input.ndim, 1)
structure = numpy.asarray(structure, dtype=bool)
if structure.ndim != input.ndim:
raise RuntimeError('structure and input must have equal rank')
for ii in structure.shape:
if ii != 3:
raise RuntimeError('structure dimensions must be equal to 3')

if not structure.flags.contiguous:
structure = structure.copy()
markers = numpy.asarray(markers)
if input.shape != markers.shape:
raise RuntimeError('input and markers must have equal shape')

integral_types = [numpy.int0,
numpy.int8,
numpy.int16,
numpy.int32,
numpy.int_,
numpy.int64,
numpy.intc,
numpy.intp]

if markers.dtype.type not in integral_types:
raise RuntimeError('marker should be of integer type')

if isinstance(output, numpy.ndarray):
if output.dtype.type not in integral_types:
raise RuntimeError('output should be of integer type')
else:
output = markers.dtype

output = _ni_support._get_output(output, input)
_nd_image.watershed_ift(input, markers, structure, output)
return output
2 changes: 1 addition & 1 deletion dask_image/ndmeasure/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def _norm_input_labels_index(input, labels=None, index=None):

if index.ndim > 1:
warnings.warn(
"Having index with dimensionality greater than 1 is undefined.",
"Having index with dimensionality (%d) greater than 1 is undefined."%index.ndim,
FutureWarning
)

Expand Down