diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py index 9dd0b4df..708f5d53 100644 --- a/skimage/filters/__init__.py +++ b/skimage/filters/__init__.py @@ -5,7 +5,7 @@ from .edges import (sobel, hsobel, vsobel, sobel_h, sobel_v, prewitt, hprewitt, vprewitt, prewitt_h, prewitt_v, roberts, roberts_positive_diagonal, roberts_negative_diagonal, roberts_pos_diag, - roberts_neg_diag) + roberts_neg_diag, laplace) from ._rank_order import rank_order from ._gabor import gabor_kernel, gabor from .thresholding import (threshold_adaptive, threshold_otsu, threshold_yen, @@ -62,6 +62,7 @@ __all__ = ['inverse', 'roberts_negative_diagonal', 'roberts_pos_diag', 'roberts_neg_diag', + 'laplace', 'denoise_tv_chambolle', 'denoise_bilateral', 'denoise_tv_bregman', diff --git a/skimage/filters/edges.py b/skimage/filters/edges.py index 1eeed4de..501dd8ea 100644 --- a/skimage/filters/edges.py +++ b/skimage/filters/edges.py @@ -37,6 +37,9 @@ ROBERTS_PD_WEIGHTS = np.array([[1, 0], ROBERTS_ND_WEIGHTS = np.array([[0, 1], [-1, 0]], dtype=np.double) +LAPLACE_WEIGHTS = np.array([[1, 1, 1], + [1, -8, 1], + [1, 1, 1]]) / 16.0 def _mask_filter_result(result, mask): """Return result after masking. @@ -762,3 +765,34 @@ def roberts_negative_diagonal(image, mask=None): """ return np.abs(roberts_neg_diag(image, mask)) + +def laplace(image, mask=None): + """Find the edges of an image using the Laplace operator. + + Parameters + ---------- + image : 2-D array + Image to process. + mask : 2-D array, optional + An optional mask to limit the application to a certain area. + Note that pixels surrounding masked regions are also masked to + prevent masked regions from affecting the result. + + Returns + ------- + output : 2-D array + The Laplace edge map. + + Notes + ----- + We use the following kernel:: + + 1 1 1 + 1 -8 1 + 1 1 1 + + """ + assert_nD(image, 2) + image = img_as_float(image) + result = convolve(image, LAPLACE_WEIGHTS) + return _mask_filter_result(result, mask) diff --git a/skimage/filters/tests/test_edges.py b/skimage/filters/tests/test_edges.py index d2c0f469..2754cbe8 100644 --- a/skimage/filters/tests/test_edges.py +++ b/skimage/filters/tests/test_edges.py @@ -335,6 +335,20 @@ def test_vprewitt_horizontal(): assert_allclose(result, 0) +def test_laplace_zeros(): + """Laplace on an array of all zeros.""" + result = filters.laplace(np.zeros((10, 10)), np.ones((10, 10), bool)) + assert (np.all(result == 0)) + + +def test_laplace_mask(): + """Laplace on a masked array should be zero.""" + np.random.seed(0) + result = filters.laplace(np.random.uniform(size=(10, 10)), + np.zeros((10, 10), bool)) + assert (np.all(result == 0)) + + def test_horizontal_mask_line(): """Horizontal edge filters mask pixels surrounding input mask.""" vgrad, _ = np.mgrid[:1:11j, :1:11j] # vertical gradient with spacing 0.1 @@ -351,7 +365,6 @@ def test_horizontal_mask_line(): result = grad_func(vgrad, mask) yield assert_close, result, expected - def test_vertical_mask_line(): """Vertical edge filters mask pixels surrounding input mask.""" _, hgrad = np.mgrid[:1:11j, :1:11j] # horizontal gradient with spacing 0.1