diff --git a/skimage/morphology/__init__.py b/skimage/morphology/__init__.py index f01fc3ed..4788c308 100644 --- a/skimage/morphology/__init__.py +++ b/skimage/morphology/__init__.py @@ -7,7 +7,7 @@ from .grey import (erosion, dilation, opening, closing, white_tophat, from .selem import (square, rectangle, diamond, disk, cube, octahedron, ball, octagon, star) from .ccomp import label -from .watershed import watershed, is_local_maximum +from .watershed import watershed from ._skeletonize import skeletonize, medial_axis from .convex_hull import convex_hull_image, convex_hull_object from .greyreconstruct import reconstruction @@ -40,7 +40,6 @@ __all__ = ['binary_erosion', 'octagon', 'label', 'watershed', - 'is_local_maximum', 'skeletonize', 'medial_axis', 'convex_hull_image', diff --git a/skimage/morphology/tests/test_watershed.py b/skimage/morphology/tests/test_watershed.py index 82531713..5dc0f07c 100644 --- a/skimage/morphology/tests/test_watershed.py +++ b/skimage/morphology/tests/test_watershed.py @@ -48,8 +48,7 @@ import unittest import numpy as np import scipy.ndimage -from skimage.morphology.watershed import watershed, \ - _slow_watershed, is_local_maximum +from skimage.morphology.watershed import watershed, _slow_watershed eps = 1e-12 @@ -387,101 +386,5 @@ class TestWatershed(unittest.TestCase): self.eight) -class TestIsLocalMaximum(unittest.TestCase): - def test_00_00_empty(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(~ result)) - - def test_01_01_one_point(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5] = 1 - labels[5, 5] = 1 - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == (labels == 1))) - - def test_01_02_adjacent_and_same(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5:6] = 1 - labels[5, 5:6] = 1 - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == (labels == 1))) - - def test_01_03_adjacent_and_different(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5] = 1 - image[5, 6] = .5 - labels[5, 5:6] = 1 - expected = (image == 1) - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == expected)) - result = is_local_maximum(image, labels) - self.assertTrue(np.all(result == expected)) - - def test_01_04_not_adjacent_and_different(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5] = 1 - image[5, 8] = .5 - labels[image > 0] = 1 - expected = (labels == 1) - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == expected)) - - def test_01_05_two_objects(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5] = 1 - image[5, 15] = .5 - labels[5, 5] = 1 - labels[5, 15] = 2 - expected = (labels > 0) - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == expected)) - - def test_01_06_adjacent_different_objects(self): - image = np.zeros((10, 20)) - labels = np.zeros((10, 20), int) - image[5, 5] = 1 - image[5, 6] = .5 - labels[5, 5] = 1 - labels[5, 6] = 2 - expected = (labels > 0) - result = is_local_maximum(image, labels, np.ones((3, 3), bool)) - self.assertTrue(np.all(result == expected)) - - def test_02_01_four_quadrants(self): - np.random.seed(21) - image = np.random.uniform(size=(40, 60)) - i, j = np.mgrid[0:40, 0:60] - labels = 1 + (i >= 20) + (j >= 30) * 2 - i, j = np.mgrid[-3:4, -3:4] - footprint = (i * i + j * j <= 9) - expected = np.zeros(image.shape, float) - for imin, imax in ((0, 20), (20, 40)): - for jmin, jmax in ((0, 30), (30, 60)): - expected[imin:imax, jmin:jmax] = scipy.ndimage.maximum_filter( - image[imin:imax, jmin:jmax], footprint=footprint) - expected = (expected == image) - result = is_local_maximum(image, labels, footprint) - self.assertTrue(np.all(result == expected)) - - def test_03_01_disk_1(self): - '''regression test of img-1194, footprint = [1] - - Test is_local_maximum when every point is a local maximum - ''' - np.random.seed(31) - image = np.random.uniform(size=(10, 20)) - footprint = np.array([[1]]) - result = is_local_maximum(image, np.ones((10, 20)), footprint) - self.assertTrue(np.all(result)) - result = is_local_maximum(image, footprint=footprint) - self.assertTrue(np.all(result)) - if __name__ == "__main__": np.testing.run_module_suite() diff --git a/skimage/morphology/watershed.py b/skimage/morphology/watershed.py index 097e3129..c9fb1789 100644 --- a/skimage/morphology/watershed.py +++ b/skimage/morphology/watershed.py @@ -116,7 +116,9 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): >>> # to the background >>> from scipy import ndimage >>> distance = ndimage.distance_transform_edt(image) - >>> local_maxi = is_local_maximum(distance, image, np.ones((3, 3))) + >>> from skimage.feature import peak_local_max + >>> local_maxi = peak_local_max(distance, labels=image, + ... footprint=np.ones((3, 3))) >>> markers = ndimage.label(local_maxi)[0] >>> labels = watershed(-distance, markers, mask=image) @@ -224,79 +226,6 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): return c_output -@deprecated('feature.peak_local_max') -def is_local_maximum(image, labels=None, footprint=None): - """ - Return a boolean array of points that are local maxima - - Parameters - ---------- - image: ndarray (2-D, 3-D, ...) - intensity image - labels: ndarray, optional - find maxima only within labels. Zero is reserved for background. - footprint: ndarray of bools, optional - binary mask indicating the neighborhood to be examined - `footprint` must be a matrix with odd dimensions, the center is taken - to be the point in question. - - Returns - ------- - result: ndarray of bools - mask that is True for pixels that are local maxima of `image` - - See also - -------- - skimage.feature.peak_local_max: Unified peak finding backend. - The more capable backend for finding local maxima. - - Notes - ----- - This function is now a wrapper for skimage.feature.peak_local_max() and is - retained only for convenience and backward compatibility. - - Examples - -------- - >>> image = np.zeros((4, 4)) - >>> image[1, 2] = 2 - >>> image[3, 3] = 1 - >>> image - array([[ 0., 0., 0., 0.], - [ 0., 0., 2., 0.], - [ 0., 0., 0., 0.], - [ 0., 0., 0., 1.]]) - >>> is_local_maximum(image) - array([[ True, False, False, False], - [ True, False, True, False], - [ True, False, False, False], - [ True, True, False, True]], dtype=bool) - >>> image = np.arange(16).reshape((4, 4)) - >>> labels = np.array([[1, 2], [3, 4]]) - >>> labels = np.repeat(np.repeat(labels, 2, axis=0), 2, axis=1) - >>> labels - array([[1, 1, 2, 2], - [1, 1, 2, 2], - [3, 3, 4, 4], - [3, 3, 4, 4]]) - >>> image - array([[ 0, 1, 2, 3], - [ 4, 5, 6, 7], - [ 8, 9, 10, 11], - [12, 13, 14, 15]]) - >>> is_local_maximum(image, labels=labels) - array([[False, False, False, False], - [False, True, False, True], - [False, False, False, False], - [False, True, False, True]], dtype=bool) - - """ - # call import here to prevent circular imports - from ..feature import peak_local_max - return peak_local_max(image, labels=labels, min_distance=1, - threshold_rel=0, footprint=footprint, - indices=False, exclude_border=False) - - # ---------------------- deprecated ------------------------------ # Deprecate slower pure-Python code, that we keep only for # pedagogical purposes