From a74878c75b2c91ff3634d81fabf062145eaac922 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Fri, 19 Feb 2016 15:36:12 +0000 Subject: [PATCH 01/11] Updated exclude_border to not use min_distance --- skimage/feature/peak.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index 0cc1b26d..f946273d 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -4,7 +4,7 @@ from ..filters import rank_order def peak_local_max(image, min_distance=1, threshold_abs=None, - threshold_rel=None, exclude_border=True, indices=True, + threshold_rel=None, exclude_border=1, indices=True, num_peaks=np.inf, footprint=None, labels=None): """Find peaks in an image as coordinate list or boolean mask. @@ -24,17 +24,16 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, min_distance : int, optional Minimum number of pixels separating peaks in a region of `2 * min_distance + 1` (i.e. peaks are separated by at least - `min_distance`). If `exclude_border` is True, this value also excludes - a border `min_distance` from the image boundary. + `min_distance`). To find the maximum number of peaks, use `min_distance=1`. threshold_abs : float, optional Minimum intensity of peaks. By default, the absolute threshold is the minimum intensity of the image. threshold_rel : float, optional Minimum intensity of peaks, calculated as `max(image) * threshold_rel`. - exclude_border : bool, optional - If True, `min_distance` excludes peaks from the border of the image as - well as from each other. + exclude_border : int, optional + If nonzero, `exclude_border` excludes peaks from + within `exclude_border` of the border of the image. indices : bool, optional If True, the output will be an array representing peak coordinates. If False, the output will be a boolean array shaped as @@ -89,7 +88,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, >>> img2 = np.zeros((20, 20, 20)) >>> img2[10, 10, 10] = 1 - >>> peak_local_max(img2, exclude_border=False) + >>> peak_local_max(img2, exclude_border=0) array([[10, 10, 10]]) """ @@ -137,12 +136,12 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, image_max = ndi.maximum_filter(image, size=size, mode='constant') mask = image == image_max - if exclude_border and (footprint is not None or min_distance > 0): + if exclude_border and (footprint is not None): # zero out the image borders for i in range(mask.ndim): mask = mask.swapaxes(0, i) remove = (footprint.shape[i] if footprint is not None - else 2 * min_distance) + else exclude_border) mask[:remove // 2] = mask[-remove // 2:] = False mask = mask.swapaxes(0, i) From 8f9a9fa388f47207e7cb6200cb585a4674604b34 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Fri, 19 Feb 2016 16:10:29 +0000 Subject: [PATCH 02/11] Minor update to docstring --- skimage/feature/peak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index f946273d..f31fb9ef 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -33,7 +33,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, Minimum intensity of peaks, calculated as `max(image) * threshold_rel`. exclude_border : int, optional If nonzero, `exclude_border` excludes peaks from - within `exclude_border` of the border of the image. + within `exclude_border`-pixels of the border of the image. indices : bool, optional If True, the output will be an array representing peak coordinates. If False, the output will be a boolean array shaped as From 0873a6fc9fe3b6014e24e5bf862e7ae7dfc1113e Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Fri, 19 Feb 2016 16:16:49 +0000 Subject: [PATCH 03/11] Factor of 2 in remove added (due to footprint) --- skimage/feature/peak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index f31fb9ef..110a629a 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -141,7 +141,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, for i in range(mask.ndim): mask = mask.swapaxes(0, i) remove = (footprint.shape[i] if footprint is not None - else exclude_border) + else exclude_border*2) mask[:remove // 2] = mask[-remove // 2:] = False mask = mask.swapaxes(0, i) From d2917a60287dddd52840677d212c8807f5381261 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Fri, 19 Feb 2016 16:17:36 +0000 Subject: [PATCH 04/11] Factor of 2 : PEP8 adjustment --- skimage/feature/peak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index 110a629a..88a71b2a 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -141,7 +141,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, for i in range(mask.ndim): mask = mask.swapaxes(0, i) remove = (footprint.shape[i] if footprint is not None - else exclude_border*2) + else 2 * exclude_border) mask[:remove // 2] = mask[-remove // 2:] = False mask = mask.swapaxes(0, i) From 5e6c98ac010416829c7839286e0a9bc647b062cc Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Mon, 22 Feb 2016 10:06:40 +0000 Subject: [PATCH 05/11] Added backwards compatibility for `exclude_border` --- skimage/feature/peak.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index 88a71b2a..6b90d7df 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -92,6 +92,9 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, array([[10, 10, 10]]) """ + + if type(exclude_border) == bool: + exclude_border = min_distance if exclude_border else 0 out = np.zeros_like(image, dtype=np.bool) From 25d15c603d837a19f9d281ff8bee9dfbadc22ea9 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Tue, 23 Feb 2016 22:17:28 +0000 Subject: [PATCH 06/11] Updated default value to be backwards compatible --- skimage/feature/peak.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index 6b90d7df..b4a0d44a 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -4,7 +4,7 @@ from ..filters import rank_order def peak_local_max(image, min_distance=1, threshold_abs=None, - threshold_rel=None, exclude_border=1, indices=True, + threshold_rel=None, exclude_border=True, indices=True, num_peaks=np.inf, footprint=None, labels=None): """Find peaks in an image as coordinate list or boolean mask. @@ -92,7 +92,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, array([[10, 10, 10]]) """ - + if type(exclude_border) == bool: exclude_border = min_distance if exclude_border else 0 From 7b23b83d21aa1349ad36072ccaa22926f706332a Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Tue, 23 Feb 2016 22:24:36 +0000 Subject: [PATCH 07/11] Updated test_peak for new exclude_border --- skimage/feature/tests/test_peak.py | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/skimage/feature/tests/test_peak.py b/skimage/feature/tests/test_peak.py index 40292cd9..0c6ce754 100644 --- a/skimage/feature/tests/test_peak.py +++ b/skimage/feature/tests/test_peak.py @@ -109,7 +109,7 @@ def test_reorder_labels(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert (result == expected).all() @@ -127,7 +127,7 @@ def test_indices_with_labels(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, - indices=True, exclude_border=False) + indices=True, exclude_border=0) assert (result == np.transpose(expected.nonzero())).all() @@ -145,7 +145,7 @@ def test_ndarray_exclude_border(): nd_image[2,2,2] = 1 expected = np.zeros_like(nd_image, dtype=np.bool) expected[2,2,2] = True - result = peak.peak_local_max(nd_image, min_distance=2, indices=False) + result = peak.peak_local_max(nd_image, exclude_border=2, indices=False) assert (result == expected).all() @@ -155,7 +155,7 @@ def test_empty(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(~ result) @@ -167,7 +167,7 @@ def test_one_point(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == (labels == 1)) @@ -179,7 +179,7 @@ def test_adjacent_and_same(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == (labels == 1)) @@ -193,11 +193,11 @@ def test_adjacent_and_different(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) @@ -211,7 +211,7 @@ def test_not_adjacent_and_different(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) @@ -226,7 +226,7 @@ def test_two_objects(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) @@ -241,7 +241,7 @@ def test_adjacent_different_objects(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) @@ -259,7 +259,7 @@ def test_four_quadrants(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, footprint=footprint, min_distance=1, threshold_rel=0, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result == expected) @@ -273,10 +273,10 @@ def test_disk(): footprint=footprint, min_distance=1, threshold_rel=0, threshold_abs=-1, indices=False, - exclude_border=False) + exclude_border=0) assert np.all(result) result = peak.peak_local_max(image, footprint=footprint, threshold_abs=-1, - indices=False, exclude_border=False) + indices=False, exclude_border=0) assert np.all(result) @@ -289,7 +289,7 @@ def test_3D(): assert_equal(peak.peak_local_max(image, min_distance=6, threshold_rel=0), [[15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0, - exclude_border=False), + exclude_border=0), [[5, 5, 5], [15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=5, threshold_rel=0), [[5, 5, 5], [15, 15, 15]]) @@ -304,7 +304,7 @@ def test_4D(): assert_equal(peak.peak_local_max(image, min_distance=6, threshold_rel=0), [[15, 15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0, - exclude_border=False), + exclude_border=0), [[5, 5, 5, 5], [15, 15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=5, threshold_rel=0), [[5, 5, 5, 5], [15, 15, 15, 15]]) From c0e3dcc69f60045bec37eedf0469727f7b37c2b3 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Wed, 24 Feb 2016 00:02:41 +0000 Subject: [PATCH 08/11] Reverted tests to boolean exclude_border --- skimage/feature/peak.py | 2 +- skimage/feature/tests/test_peak.py | 33 +++++++++++++++--------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index b4a0d44a..a27622f0 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -94,7 +94,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, """ if type(exclude_border) == bool: - exclude_border = min_distance if exclude_border else 0 + exclude_border = min_distance if exclude_border else 0 out = np.zeros_like(image, dtype=np.bool) diff --git a/skimage/feature/tests/test_peak.py b/skimage/feature/tests/test_peak.py index 0c6ce754..6b94daf5 100644 --- a/skimage/feature/tests/test_peak.py +++ b/skimage/feature/tests/test_peak.py @@ -109,7 +109,7 @@ def test_reorder_labels(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert (result == expected).all() @@ -127,7 +127,7 @@ def test_indices_with_labels(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, footprint=footprint, - indices=True, exclude_border=0) + indices=True, exclude_border=False) assert (result == np.transpose(expected.nonzero())).all() @@ -145,7 +145,8 @@ def test_ndarray_exclude_border(): nd_image[2,2,2] = 1 expected = np.zeros_like(nd_image, dtype=np.bool) expected[2,2,2] = True - result = peak.peak_local_max(nd_image, exclude_border=2, indices=False) + result = peak.peak_local_max(nd_image, min_distance=2, + exclude_border=2, indices=False) assert (result == expected).all() @@ -155,7 +156,7 @@ def test_empty(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(~ result) @@ -167,7 +168,7 @@ def test_one_point(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == (labels == 1)) @@ -179,7 +180,7 @@ def test_adjacent_and_same(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == (labels == 1)) @@ -193,11 +194,11 @@ def test_adjacent_and_different(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) result = peak.peak_local_max(image, labels=labels, min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) @@ -211,7 +212,7 @@ def test_not_adjacent_and_different(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) @@ -226,7 +227,7 @@ def test_two_objects(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) @@ -241,7 +242,7 @@ def test_adjacent_different_objects(): result = peak.peak_local_max(image, labels=labels, footprint=np.ones((3, 3), bool), min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) @@ -259,7 +260,7 @@ def test_four_quadrants(): expected = (expected == image) result = peak.peak_local_max(image, labels=labels, footprint=footprint, min_distance=1, threshold_rel=0, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result == expected) @@ -273,10 +274,10 @@ def test_disk(): footprint=footprint, min_distance=1, threshold_rel=0, threshold_abs=-1, indices=False, - exclude_border=0) + exclude_border=False) assert np.all(result) result = peak.peak_local_max(image, footprint=footprint, threshold_abs=-1, - indices=False, exclude_border=0) + indices=False, exclude_border=False) assert np.all(result) @@ -289,7 +290,7 @@ def test_3D(): assert_equal(peak.peak_local_max(image, min_distance=6, threshold_rel=0), [[15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0, - exclude_border=0), + exclude_border=False), [[5, 5, 5], [15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=5, threshold_rel=0), [[5, 5, 5], [15, 15, 15]]) @@ -304,7 +305,7 @@ def test_4D(): assert_equal(peak.peak_local_max(image, min_distance=6, threshold_rel=0), [[15, 15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0, - exclude_border=0), + exclude_border=False), [[5, 5, 5, 5], [15, 15, 15, 15]]) assert_equal(peak.peak_local_max(image, min_distance=5, threshold_rel=0), [[5, 5, 5, 5], [15, 15, 15, 15]]) From 20d4e7dde8dc528ad27fb3ee368d8af7ef108979 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Wed, 24 Feb 2016 01:36:21 +0000 Subject: [PATCH 09/11] Finally fixed issue: Issue Was with remnant of min_distance logic (i.e. `footprint is not None` --- skimage/feature/peak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/feature/peak.py b/skimage/feature/peak.py index a27622f0..c4d1aa32 100644 --- a/skimage/feature/peak.py +++ b/skimage/feature/peak.py @@ -139,7 +139,7 @@ def peak_local_max(image, min_distance=1, threshold_abs=None, image_max = ndi.maximum_filter(image, size=size, mode='constant') mask = image == image_max - if exclude_border and (footprint is not None): + if exclude_border: # zero out the image borders for i in range(mask.ndim): mask = mask.swapaxes(0, i) From 488866cfe51397b6afd811de4c7c3d171fa26e41 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Wed, 24 Feb 2016 02:06:09 +0000 Subject: [PATCH 10/11] Added additional tests of exclude_border values --- skimage/feature/tests/test_peak.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/skimage/feature/tests/test_peak.py b/skimage/feature/tests/test_peak.py index 6b94daf5..e0bc87e5 100644 --- a/skimage/feature/tests/test_peak.py +++ b/skimage/feature/tests/test_peak.py @@ -145,9 +145,34 @@ def test_ndarray_exclude_border(): nd_image[2,2,2] = 1 expected = np.zeros_like(nd_image, dtype=np.bool) expected[2,2,2] = True + expectedNoBorder = nd_image > 0 result = peak.peak_local_max(nd_image, min_distance=2, exclude_border=2, indices=False) - assert (result == expected).all() + assert_equal(result, expected) + # Check that bools work as expected + assert_equal( + peak.peak_local_max(nd_image, min_distance=2, + exclude_border=2, indices=False) + peak.peak_local_max(nd_image, min_distance=2, + exclude_border=True, indices=False) + ) + assert_equal( + peak.peak_local_max(nd_image, min_distance=2, + exclude_border=0, indices=False) + peak.peak_local_max(nd_image, min_distance=2, + exclude_border=False, indices=False) + ) + # Check both versions with no border + assert_equal( + peak.peak_local_max(nd_image, min_distance=2, + exclude_border=0, indices=False) + expectedNoBorder, + ) + assert_equal( + peak.peak_local_max(nd_image, + exclude_border=False, indices=False) + expectedNoBorder, + ) def test_empty(): From 4244bb17a84a397633c8c9c95b7b407c84539630 Mon Sep 17 00:00:00 2001 From: Jeremy Metz Date: Wed, 24 Feb 2016 02:27:14 +0000 Subject: [PATCH 11/11] Fix: missing colon on additional tests of exclude_border values --- skimage/feature/tests/test_peak.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skimage/feature/tests/test_peak.py b/skimage/feature/tests/test_peak.py index e0bc87e5..c921661c 100644 --- a/skimage/feature/tests/test_peak.py +++ b/skimage/feature/tests/test_peak.py @@ -152,25 +152,25 @@ def test_ndarray_exclude_border(): # Check that bools work as expected assert_equal( peak.peak_local_max(nd_image, min_distance=2, - exclude_border=2, indices=False) + exclude_border=2, indices=False), peak.peak_local_max(nd_image, min_distance=2, exclude_border=True, indices=False) ) assert_equal( peak.peak_local_max(nd_image, min_distance=2, - exclude_border=0, indices=False) + exclude_border=0, indices=False), peak.peak_local_max(nd_image, min_distance=2, exclude_border=False, indices=False) ) # Check both versions with no border assert_equal( peak.peak_local_max(nd_image, min_distance=2, - exclude_border=0, indices=False) + exclude_border=0, indices=False), expectedNoBorder, ) assert_equal( peak.peak_local_max(nd_image, - exclude_border=False, indices=False) + exclude_border=False, indices=False), expectedNoBorder, )