Simplify output handling for binary morphology.

This commit is contained in:
Stefan van der Walt
2013-10-12 19:10:23 +02:00
parent 2c7bf856f5
commit b022dd6dfb
2 changed files with 18 additions and 71 deletions
+18 -50
View File
@@ -3,46 +3,15 @@ import numpy as np
from scipy import ndimage
def _convolve(image, selem, out, cval):
# determine the smallest integer dtype which does not overflow
selem = selem != 0
selem_sum = np.sum(selem)
if selem_sum < 2 ** 8:
out_dtype = np.uint8
else:
out_dtype = np.intp
if out is None:
out = np.zeros_like(image, dtype=out_dtype)
else:
warnings.warn('Parameter `out` is deprecated and it does not equal '
'the output image if the sum of the structuring element '
'overflows the dtype of `out`.')
iinfo = np.iinfo(out.dtype)
if iinfo.max - iinfo.min < selem_sum:
raise ValueError('Sum of structuring (=%d) element results in '
'overflow for dtype of `out`. You must raise the '
'bit-depth.')
conv = ndimage.convolve(image > 0, selem, output=out,
mode='constant', cval=cval)
if conv is not None:
out = conv
return out, selem_sum
def binary_erosion(image, selem, out=None):
"""Return fast binary morphological erosion of an image.
This function returns the same result as greyscale erosion but performs
faster for binary images.
Morphological erosion sets a pixel at (i,j) to the minimum over all pixels
in the neighborhood centered at (i,j). Erosion shrinks bright regions and
enlarges dark regions.
Morphological erosion sets a pixel at ``(i,j)`` to the minimum over all
pixels in the neighborhood centered at ``(i,j)``. Erosion shrinks bright
regions and enlarges dark regions.
Parameters
----------
@@ -50,20 +19,20 @@ def binary_erosion(image, selem, out=None):
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
out : ndarray of bool
The array to store the result of the morphology. If None is
passed, a new array will be allocated.
Returns
-------
eroded : bool array
eroded : ndarray of bool
The result of the morphological erosion.
"""
out, selem_sum = _convolve(image, selem, out, 1)
return np.array(np.equal(out, selem_sum, out=out), dtype=np.bool,
copy=False)
selem = (selem != 0)
selem_sum = np.sum(selem)
out = ndimage.convolve(image > 0, selem, mode='constant', cval=1)
return np.equal(out, selem_sum, out=out)
def binary_dilation(image, selem, out=None):
@@ -83,19 +52,19 @@ def binary_dilation(image, selem, out=None):
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
out : ndarray of bool
The array to store the result of the morphology. If None, is
passed, a new array will be allocated.
Returns
-------
dilated : bool array
dilated : ndarray of bool
The result of the morphological dilation.
"""
out, _ = _convolve(image, selem, out, 0)
return np.array(np.not_equal(out, 0, out=out), dtype=np.bool, copy=False)
selem = (selem != 0)
out = ndimage.convolve(image > 0, selem, mode='constant', cval=0)
return np.not_equal(out, 0, out=out)
def binary_opening(image, selem, out=None):
@@ -115,17 +84,16 @@ def binary_opening(image, selem, out=None):
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
out : ndarray of bool
The array to store the result of the morphology. If None
is passed, a new array will be allocated.
Returns
-------
opening : bool array
opening : ndarray of bool
The result of the morphological opening.
"""
eroded = binary_erosion(image, selem)
out = binary_dilation(eroded, selem, out=out)
return out
@@ -148,13 +116,13 @@ def binary_closing(image, selem, out=None):
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1's and 0's.
out : ndarray
out : ndarray of bool
The array to store the result of the morphology. If None,
is passed, a new array will be allocated.
Returns
-------
closing : bool array
closing : ndarray of bool
The result of the morphological closing.
"""
-21
View File
@@ -17,27 +17,6 @@ def test_non_square_image():
testing.assert_array_equal(binary_res, grey_res)
def test_selem_overflow():
strel = np.ones((17, 17), dtype=np.uint8)
img = np.zeros((20, 20))
img[2:19, 2:19] = 1
binary_res = binary.binary_erosion(img, strel)
grey_res = img_as_bool(grey.erosion(img, strel))
testing.assert_array_equal(binary_res, grey_res)
def test_selem_overflow_exception():
strel = np.ones((17, 17), dtype=np.uint8)
img = np.zeros((20, 20))
img[2:19, 2:19] = 1
out = np.zeros((20, 20), dtype=np.uint8)
testing.assert_raises(ValueError, binary.binary_erosion, img, strel, out)
out = np.zeros((20, 20), dtype=np.uint16)
binary_res = binary.binary_erosion(img, strel, out=out)
grey_res = img_as_bool(grey.erosion(img, strel))
testing.assert_array_equal(binary_res, grey_res)
def test_binary_erosion():
strel = selem.square(3)
binary_res = binary.binary_erosion(bw_lena, strel)