From 0c8b7afa9201a6b6438c4ae287302c3351b461fb Mon Sep 17 00:00:00 2001 From: "John (EBo) David" Date: Wed, 30 Jan 2019 15:01:48 -0500 Subject: [PATCH] Added a port of scipy.ndimage.measurement.watershed. dask.array.atop was depricated and moved to dask.array.blockwise. --- dask_image/ndmeasure/__init__.py | 94 ++++++++++++++++++++++++++++++++ dask_image/ndmeasure/_utils.py | 2 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/dask_image/ndmeasure/__init__.py b/dask_image/ndmeasure/__init__.py index e383a378..c87b201e 100644 --- a/dask_image/ndmeasure/__init__.py +++ b/dask_image/ndmeasure/__init__.py @@ -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 # + #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 diff --git a/dask_image/ndmeasure/_utils.py b/dask_image/ndmeasure/_utils.py index 6817ac7e..14f92d3e 100644 --- a/dask_image/ndmeasure/_utils.py +++ b/dask_image/ndmeasure/_utils.py @@ -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 )