Merge pull request #1763 from glemaitre/laplace-edge-detector-wrapper

Added the Laplacian operator
This commit is contained in:
Juan Nunez-Iglesias
2015-10-28 20:06:10 +11:00
3 changed files with 64 additions and 2 deletions
+2 -1
View File
@@ -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',
+34
View File
@@ -14,6 +14,7 @@ from .. import img_as_float
from .._shared.utils import assert_nD, deprecated
from scipy.ndimage import convolve, binary_erosion, generate_binary_structure
from ..restoration.uft import laplacian
EROSION_SELEM = generate_binary_structure(2, 2)
@@ -175,6 +176,7 @@ def hsobel(image, mask=None):
Parameters
----------
image : 2-D array
Image to process.
mask : 2-D array, optional
@@ -762,3 +764,35 @@ def roberts_negative_diagonal(image, mask=None):
"""
return np.abs(roberts_neg_diag(image, mask))
def laplace(image, ksize=3, mask=None):
"""Find the edges of an image using the Laplace operator.
Parameters
----------
image : ndarray
Image to process.
ksize : int, optional
Define the size of the discrete Laplacian operator such that it
will have a size of (ksize,) * image.ndim.
mask : ndarray, 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 : ndarray
The Laplace edge map.
Notes
-----
The Laplacian operator is generated using the function
skimage.restoration.uft.laplacian().
"""
image = img_as_float(image)
# Create the discrete Laplacian operator - We keep only the real part of the filter
_, laplace_op = laplacian(image.ndim, (ksize, ) * image.ndim)
result = convolve(image, laplace_op)
return _mask_filter_result(result, mask)
+28 -1
View File
@@ -335,6 +335,34 @@ def test_vprewitt_horizontal():
assert_allclose(result, 0)
def test_laplace_zeros():
"""Laplace on a square image."""
# Create a synthetic 2D image
image = np.zeros((9, 9))
image[3:-3, 3:-3] = 1
result = filters.laplace(image)
res_chk = np.array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., -1., -1., -1., 0., 0., 0.],
[ 0., 0., -1., 2., 1., 2., -1., 0., 0.],
[ 0., 0., -1., 1., 0., 1., -1., 0., 0.],
[ 0., 0., -1., 2., 1., 2., -1., 0., 0.],
[ 0., 0., 0., -1., -1., -1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
assert_allclose(result, res_chk)
def test_laplace_mask():
"""Laplace on a masked array should be zero."""
# Create a synthetic 2D image
image = np.zeros((9, 9))
image[3:-3, 3:-3] = 1
# Define the mask
result = filters.laplace(image, ksize=3, mask=np.zeros((9, 9), 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 +379,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