From acc1ee0dad4dd56e18b5d21dcddd8cf91460fe97 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Tue, 24 Mar 2015 13:55:37 -0700 Subject: [PATCH 1/3] Allow clear_border to operate on labeled images --- skimage/segmentation/_clear_border.py | 42 +++++++++++-------- .../segmentation/tests/test_clear_border.py | 17 +++++++- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/skimage/segmentation/_clear_border.py b/skimage/segmentation/_clear_border.py index 266e17e2..318f8790 100644 --- a/skimage/segmentation/_clear_border.py +++ b/skimage/segmentation/_clear_border.py @@ -1,37 +1,39 @@ import numpy as np -from scipy.ndimage import label +#from scipy.ndimage import label +from ..measure import label -def clear_border(image, buffer_size=0, bgval=0): - """Clear objects connected to image border. +def clear_border(labels, buffer_size=0, bgval=0): + """Clear objects connected to the label image border. - The changes will be applied to the input image. + The changes will be applied directly to the input. Parameters ---------- - image : (N, M) array - Binary image. + labels : (N, M) array of int + Label or binary image. buffer_size : int, optional - Define additional buffer around image border. + The width of the border examined. By default, only objects + that touch the outside of the image are removed. bgval : float or int, optional - Value for cleared objects. + Cleared objects are set to this value. Returns ------- - image : (N, M) array - Cleared binary image. + labels : (N, M) array + Cleared binary image. Note that the input label image is modified. Examples -------- >>> import numpy as np >>> from skimage.segmentation import clear_border - >>> image = np.array([[0, 0, 0, 0, 0, 0, 0, 1, 0], - ... [0, 0, 0, 0, 1, 0, 0, 0, 0], - ... [1, 0, 0, 1, 0, 1, 0, 0, 0], - ... [0, 0, 1, 1, 1, 1, 1, 0, 0], - ... [0, 1, 1, 1, 1, 1, 1, 1, 0], - ... [0, 0, 0, 0, 0, 0, 0, 0, 0]]) - >>> clear_border(image) + >>> labels = np.array([[0, 0, 0, 0, 0, 0, 0, 1, 0], + ... [0, 0, 0, 0, 1, 0, 0, 0, 0], + ... [1, 0, 0, 1, 0, 1, 0, 0, 0], + ... [0, 0, 1, 1, 1, 1, 1, 0, 0], + ... [0, 1, 1, 1, 1, 1, 1, 1, 0], + ... [0, 0, 0, 0, 0, 0, 0, 0, 0]]) + >>> clear_border(labels) array([[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0, 0], @@ -40,6 +42,7 @@ def clear_border(image, buffer_size=0, bgval=0): [0, 0, 0, 0, 0, 0, 0, 0, 0]]) """ + image = labels rows, cols = image.shape if buffer_size >= rows or buffer_size >= cols: @@ -53,7 +56,10 @@ def clear_border(image, buffer_size=0, bgval=0): borders[:, :ext] = True borders[:, - ext:] = True - labels, number = label(image) + # Re-label, in case we are dealing with a binary image + # and to get consistent labeling + labels = label(image, background=0) + 1 + number = np.max(labels) + 1 # determine all objects that are connected to borders borders_indices = np.unique(labels[borders]) diff --git a/skimage/segmentation/tests/test_clear_border.py b/skimage/segmentation/tests/test_clear_border.py index 5d6852cf..67739426 100644 --- a/skimage/segmentation/tests/test_clear_border.py +++ b/skimage/segmentation/tests/test_clear_border.py @@ -24,9 +24,24 @@ def test_clear_border(): assert_array_equal(result, np.zeros(result.shape)) # test background value - result = clear_border(image.copy(), 1, 2) + result = clear_border(image.copy(), buffer_size=1, bgval=2) assert_array_equal(result, 2 * np.ones_like(image)) +def test_clear_border_non_binary(): + image = np.array([[1, 2, 3, 1, 2], + [3, 4, 5, 4, 2], + [3, 4, 5, 4, 2], + [3, 3, 2, 1, 2]]) + + result = clear_border(image.copy()) + expected = np.array([[0, 0, 0, 0, 0], + [0, 4, 5, 4, 0], + [0, 4, 5, 4, 0], + [0, 0, 0, 0, 0]]) + + assert_array_equal(result, expected) + + if __name__ == "__main__": np.testing.run_module_suite() From 3b0179e4c12a4f29eb1b19e117c8659c24d5fc85 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 8 May 2015 22:26:03 -0700 Subject: [PATCH 2/3] Improve test robustness --- skimage/segmentation/tests/test_clear_border.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/segmentation/tests/test_clear_border.py b/skimage/segmentation/tests/test_clear_border.py index 67739426..51431260 100644 --- a/skimage/segmentation/tests/test_clear_border.py +++ b/skimage/segmentation/tests/test_clear_border.py @@ -30,13 +30,13 @@ def test_clear_border(): def test_clear_border_non_binary(): image = np.array([[1, 2, 3, 1, 2], - [3, 4, 5, 4, 2], + [3, 3, 5, 4, 2], [3, 4, 5, 4, 2], [3, 3, 2, 1, 2]]) result = clear_border(image.copy()) expected = np.array([[0, 0, 0, 0, 0], - [0, 4, 5, 4, 0], + [0, 0, 5, 4, 0], [0, 4, 5, 4, 0], [0, 0, 0, 0, 0]]) From 6fc4e11b9a871756eb35f32ff899016af02d858f Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 8 May 2015 22:32:29 -0700 Subject: [PATCH 3/3] Add in-place operation --- skimage/segmentation/_clear_border.py | 9 +++++++-- .../segmentation/tests/test_clear_border.py | 20 +++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/skimage/segmentation/_clear_border.py b/skimage/segmentation/_clear_border.py index 318f8790..bc972754 100644 --- a/skimage/segmentation/_clear_border.py +++ b/skimage/segmentation/_clear_border.py @@ -3,7 +3,7 @@ import numpy as np from ..measure import label -def clear_border(labels, buffer_size=0, bgval=0): +def clear_border(labels, buffer_size=0, bgval=0, in_place=False): """Clear objects connected to the label image border. The changes will be applied directly to the input. @@ -17,11 +17,13 @@ def clear_border(labels, buffer_size=0, bgval=0): that touch the outside of the image are removed. bgval : float or int, optional Cleared objects are set to this value. + in_place : bool, optional + Whether or not to manipulate the labels array in-place. Returns ------- labels : (N, M) array - Cleared binary image. Note that the input label image is modified. + Cleared binary image. Examples -------- @@ -69,6 +71,9 @@ def clear_border(labels, buffer_size=0, bgval=0): # create mask for pixels to clear mask = label_mask[labels.ravel()].reshape(labels.shape) + if not in_place: + image = image.copy() + # clear border pixels image[mask] = bgval diff --git a/skimage/segmentation/tests/test_clear_border.py b/skimage/segmentation/tests/test_clear_border.py index 51431260..b626ea2b 100644 --- a/skimage/segmentation/tests/test_clear_border.py +++ b/skimage/segmentation/tests/test_clear_border.py @@ -1,5 +1,5 @@ import numpy as np -from numpy.testing import assert_array_equal +from numpy.testing import assert_array_equal, assert_ from skimage.segmentation import clear_border @@ -34,14 +34,30 @@ def test_clear_border_non_binary(): [3, 4, 5, 4, 2], [3, 3, 2, 1, 2]]) - result = clear_border(image.copy()) + result = clear_border(image) expected = np.array([[0, 0, 0, 0, 0], [0, 0, 5, 4, 0], [0, 4, 5, 4, 0], [0, 0, 0, 0, 0]]) assert_array_equal(result, expected) + assert_(not np.all(image == result)) +def test_clear_border_non_binary_inplace(): + image = np.array([[1, 2, 3, 1, 2], + [3, 3, 5, 4, 2], + [3, 4, 5, 4, 2], + [3, 3, 2, 1, 2]]) + + result = clear_border(image, in_place=True) + expected = np.array([[0, 0, 0, 0, 0], + [0, 0, 5, 4, 0], + [0, 4, 5, 4, 0], + [0, 0, 0, 0, 0]]) + + assert_array_equal(result, expected) + assert_array_equal(image, result) + if __name__ == "__main__": np.testing.run_module_suite()