Merge pull request #248 from ahojnnes/clear-border

Add function to clear border in binary images
This commit is contained in:
Emmanuelle Gouillart
2012-08-30 11:24:37 -07:00
3 changed files with 102 additions and 0 deletions
+1
View File
@@ -3,3 +3,4 @@ from ._felzenszwalb import felzenszwalb
from ._slic import slic
from ._quickshift import quickshift
from .boundaries import find_boundaries, visualize_boundaries
from ._clear_border import clear_border
+69
View File
@@ -0,0 +1,69 @@
import numpy as np
from scipy.ndimage import label
def clear_border(image, buffer_size=0, bgval=0):
"""Clear objects connected to image border.
The changes will be applied to the input image.
Parameters
----------
image : (N, M) array
Binary image.
buffer_size : int, optional
Define additional buffer around image border.
bgval : float or int, optional
Value for cleared objects.
Returns
-------
image : (N, M) array
Cleared binary image.
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)
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],
[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]])
"""
rows, cols = image.shape
if buffer_size >= rows or buffer_size >= cols:
raise ValueError("buffer size may not be greater than image size")
# create borders with buffer_size
borders = np.zeros_like(image, dtype=np.bool_)
ext = buffer_size + 1
borders[:ext] = True
borders[- ext:] = True
borders[:, :ext] = True
borders[:, - ext:] = True
labels, number = label(image)
# determine all objects that are connected to borders
borders_indices = np.unique(labels[borders])
indices = np.arange(number + 1)
# mask all label indices that are connected to borders
label_mask = np.in1d(indices, borders_indices)
# create mask for pixels to clear
mask = label_mask[labels.ravel()].reshape(labels.shape)
# clear border pixels
image[mask] = bgval
return image
@@ -0,0 +1,32 @@
import numpy as np
from numpy.testing import assert_array_equal, assert_equal
from skimage.segmentation import clear_border
def test_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]])
# test default case
result = clear_border(image.copy())
ref = image.copy()
ref[2, 0] = 0
ref[0, -2] = 0
assert_array_equal(result, ref)
# test buffer
result = clear_border(image.copy(), 1)
assert_array_equal(result, np.zeros(result.shape))
# test background value
result = clear_border(image.copy(), 1, 2)
assert_array_equal(result, 2 * np.ones_like(image))
if __name__ == "__main__":
np.testing.run_module_suite()