Module: morphology¶
skimage.morphology.black_tophat(image, selem) | Return black top hat of an image. |
skimage.morphology.closing(image, selem[, out]) | Return greyscale morphological closing of an image. |
skimage.morphology.convex_hull_image(image) | Compute the convex hull image of a binary image. |
skimage.morphology.diamond(radius[, dtype]) | Generates a flat, diamond-shaped structuring element of a given radius. |
skimage.morphology.dilation(image, selem[, ...]) | Return greyscale morphological dilation of an image. |
skimage.morphology.disk(radius[, dtype]) | Generates a flat, disk-shaped structuring element of a given radius. |
skimage.morphology.erosion(image, selem[, ...]) | Return greyscale morphological erosion of an image. |
skimage.morphology.greyscale_black_top_hat(...) | |
skimage.morphology.greyscale_close(*args, ...) | |
skimage.morphology.greyscale_dilate(*args, ...) | |
skimage.morphology.greyscale_erode(*args, ...) | |
skimage.morphology.greyscale_open(*args, ...) | |
skimage.morphology.greyscale_white_top_hat(...) | |
skimage.morphology.is_local_maximum(image[, ...]) | Return a boolean array of points that are local maxima |
skimage.morphology.label | Label connected regions of an integer array. |
skimage.morphology.medial_axis(image[, ...]) | Compute the medial axis transform of a binary image |
skimage.morphology.opening(image, selem[, out]) | Return greyscale morphological opening of an image. |
skimage.morphology.rectangle(width, height) | Generates a flat, rectangular-shaped structuring element of a given width and height. |
skimage.morphology.skeletonize(image) | Return the skeleton of a binary image. |
skimage.morphology.square(width[, dtype]) | Generates a flat, square-shaped structuring element. |
skimage.morphology.watershed(image, markers) | Return a matrix labeled using the watershed segmentation algorithm |
skimage.morphology.white_tophat(image, selem) | Return white top hat of an image. |
black_tophat¶
- skimage.morphology.black_tophat(image, selem, out=None)¶
Return black top hat of an image.
The black top hat of an image is defined as its morphological closing minus the original image. This operation returns the dark spots of the image that are smaller than the structuring element. Note that dark spots in the original image are bright spots after the black top hat.
Parameters : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None is passed, a new array will be allocated.
Returns : opening : uint8 array
The result of the black top filter.
Examples
>>> # Change dark peak to bright peak and subtract background >>> from skimage.morphology import square >>> dark_on_grey = np.array([[7, 6, 6, 6, 7], ... [6, 5, 4, 5, 6], ... [6, 4, 0, 4, 6], ... [6, 5, 4, 5, 6], ... [7, 6, 6, 6, 7]], dtype=np.uint8) >>> black_tophat(dark_on_grey, square(3)) array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 1, 5, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]], dtype='uint8')
closing¶
- skimage.morphology.closing(image, selem, out=None)¶
Return greyscale morphological closing of an image.
The morphological closing on an image is defined as a dilation followed by an erosion. Closing can remove small dark spots (i.e. “pepper”) and connect small bright cracks. This tends to “close” up (dark) gaps between (bright) features.
Parameters : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None, is passed, a new array will be allocated.
Returns : closing : uint8 array
The result of the morphological closing.
Examples
>>> # Close a gap between two bright lines >>> from skimage.morphology import square >>> broken_line = np.array([[0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0], ... [1, 1, 0, 1, 1], ... [0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0]], dtype=np.uint8) >>> closing(broken_line, square(3)) array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], dtype='uint8')
convex_hull_image¶
- skimage.morphology.convex_hull_image(image)¶
Compute the convex hull image of a binary image.
The convex hull is the set of pixels included in the smallest convex polygon that surround all white pixels in the input image.
Parameters : image : ndarray
Binary input image. This array is cast to bool before processing.
Returns : hull : ndarray of uint8
Binary image with pixels in convex hull set to 255.
References
[R43] http://blogs.mathworks.com/steve/2011/10/04/binary-image-convex-hull-algorithm-notes/
diamond¶
- skimage.morphology.diamond(radius, dtype=<type 'numpy.uint8'>)¶
Generates a flat, diamond-shaped structuring element of a given radius. A pixel is part of the neighborhood (i.e. labeled 1) if the city block/manhattan distance between it and the center of the neighborhood is no greater than radius.
Parameters : radius : int
The radius of the diamond-shaped structuring element.
dtype : data-type
The data type of the structuring element.
Returns : selem : ndarray
The structuring element where elements of the neighborhood are 1 and 0 otherwise.
dilation¶
- skimage.morphology.dilation(image, selem, out=None, shift_x=False, shift_y=False)¶
Return greyscale morphological dilation of an image.
Morphological dilation sets a pixel at (i,j) to the maximum over all pixels in the neighborhood centered at (i,j). Dilation enlarges bright regions and shrinks dark regions.
Parameters : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None, is passed, a new array will be allocated.
shift_x, shift_y : bool
shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides).
Returns : dilated : uint8 array
The result of the morphological dilation.
Examples
>>> # Dilation enlarges bright regions >>> from skimage.morphology import square >>> bright_pixel = np.array([[0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0], ... [0, 0, 1, 0, 0], ... [0, 0, 0, 0, 0], ... [0, 0, 0, 0, 0]], dtype=np.uint8) >>> dilation(bright_pixel, square(3)) array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]], dtype='uint8')
disk¶
- skimage.morphology.disk(radius, dtype=<type 'numpy.uint8'>)¶
Generates a flat, disk-shaped structuring element of a given radius. A pixel is within the neighborhood if the euclidean distance between it and the origin is no greater than a radius.
Parameters : radius : int
The radius of the disk-shaped structuring element.
dtype : data-type
The data type of the structuring element.
Returns : selem : ndarray
The structuring element where elements of the neighborhood are 1 and 0 otherwise.
erosion¶
- skimage.morphology.erosion(image, selem, out=None, shift_x=False, shift_y=False)¶
Return greyscale morphological erosion of an image.
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 : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None is passed, a new array will be allocated.
shift_x, shift_y : bool
shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides).
Returns : eroded : uint8 array
The result of the morphological erosion.
Examples
>>> # Erosion shrinks bright regions >>> from skimage.morphology import square >>> bright_square = np.array([[0, 0, 0, 0, 0], ... [0, 1, 1, 1, 0], ... [0, 1, 1, 1, 0], ... [0, 1, 1, 1, 0], ... [0, 0, 0, 0, 0]], dtype=np.uint8) >>> erosion(bright_square, square(3)) array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], dtype='uint8')
is_local_maximum¶
- skimage.morphology.is_local_maximum(image, labels=None, footprint=None)¶
Return a boolean array of points that are local maxima
Parameters : image: ndarray (2-D, 3-D, ...) :
intensity image
labels: ndarray, optional :
find maxima only within labels. Zero is reserved for background.
footprint: ndarray of bools, optional :
binary mask indicating the neighborhood to be examined footprint must be a matrix with odd dimensions, the center is taken to be the point in question.
Returns : result: ndarray of bools :
mask that is True for pixels that are local maxima of image
Examples
>>> image = np.zeros((4, 4)) >>> image[1, 2] = 2 >>> image[3, 3] = 1 >>> image array([[ 0., 0., 0., 0.], [ 0., 0., 2., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 1.]]) >>> is_local_maximum(image) array([[ True, False, False, False], [ True, False, True, False], [ True, False, False, False], [ True, True, False, True]], dtype='bool') >>> image = np.arange(16).reshape((4, 4)) >>> labels = np.array([[1, 2], [3, 4]]) >>> labels = np.repeat(np.repeat(labels, 2, axis=0), 2, axis=1) >>> labels array([[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]) >>> image array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) >>> is_local_maximum(image, labels=labels) array([[False, False, False, False], [False, True, False, True], [False, False, False, False], [False, True, False, True]], dtype='bool')
label¶
- skimage.morphology.label()¶
Label connected regions of an integer array.
Two pixels are connected when they are neighbors and have the same value. They can be neighbors either in a 4- or 8-connected sense:
4-connectivity 8-connectivity [ ] [ ] [ ] [ ] | \ | / [ ]--[ ]--[ ] [ ]--[ ]--[ ] | / | \ [ ] [ ] [ ] [ ]
Parameters : input : ndarray of dtype int
Image to label.
neighbors : {4, 8}, int
Whether to use 4- or 8-connectivity.
background : int
Consider all pixels with this value as background pixels, and label them as -1.
Returns : labels : ndarray of dtype int
Labeled array, where all connected regions are assigned the same integer value.
Examples
>>> x = np.eye(3).astype(int) >>> print x [[1 0 0] [0 1 0] [0 0 1]]
>>> print m.label(x, neighbors=4) [[0 1 1] [2 3 1] [2 2 4]]
>>> print m.label(x, neighbors=8) [[0 1 1] [1 0 1] [1 1 0]]
>>> x = np.array([[1, 0, 0], ... [1, 1, 5], ... [0, 0, 0]])
>>> print m.label(x, background=0) [[ 0 -1 -1] [ 0 0 1] [-1 -1 -1]]
medial_axis¶
- skimage.morphology.medial_axis(image, mask=None, return_distance=False)¶
Compute the medial axis transform of a binary image
Parameters : image : binary ndarray
mask : binary ndarray, optional
If a mask is given, only those elements with a true value in mask are used for computing the medial axis.
return_distance : bool, optional
If true, the distance transform is returned as well as the skeleton.
Returns : out : ndarray of bools
Medial axis transform of the image
dist : ndarray of ints
Distance transform of the image (only returned if return_distance is True)
See also
Notes
This algorithm computes the medial axis transform of an image as the ridges of its distance transform.
- The different steps of the algorithm are as follows
- A lookup table is used, that assigns 0 or 1 to each configuration of the 3x3 binary square, whether the central pixel should be removed or kept. We want a point to be removed if it has more than one neighbor and if removing it does not change the number of connected components.
- The distance transform to the background is computed, as well as the cornerness of the pixel.
- The foreground (value of 1) points are ordered by the distance transform, then the cornerness.
- A cython function is called to reduce the image to its skeleton. It processes pixels in the order determined at the previous step, and removes or maintains a pixel according to the lookup table. Because of the ordering, it is possible to process all pixels in only one pass.
Examples
>>> square = np.zeros((7, 7), dtype=np.uint8) >>> square[1:-1, 2:-2] = 1 >>> square array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0]], dtype=uint8) >>> morphology.medial_axis(square).astype(np.uint8) array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
opening¶
- skimage.morphology.opening(image, selem, out=None)¶
Return greyscale morphological opening of an image.
The morphological opening on an image is defined as an erosion followed by a dilation. Opening can remove small bright spots (i.e. “salt”) and connect small dark cracks. This tends to “open” up (dark) gaps between (bright) features.
Parameters : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None is passed, a new array will be allocated.
Returns : opening : uint8 array
The result of the morphological opening.
Examples
>>> # Open up gap between two bright regions (but also shrink regions) >>> from skimage.morphology import square >>> bad_connection = np.array([[1, 0, 0, 0, 1], ... [1, 1, 0, 1, 1], ... [1, 1, 1, 1, 1], ... [1, 1, 0, 1, 1], ... [1, 0, 0, 0, 1]], dtype=np.uint8) >>> opening(bad_connection, square(3)) array([[0, 0, 0, 0, 0], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [0, 0, 0, 0, 0]], dtype='uint8')
rectangle¶
- skimage.morphology.rectangle(width, height, dtype=<type 'numpy.uint8'>)¶
Generates a flat, rectangular-shaped structuring element of a given width and height. Every pixel in the rectangle belongs to the neighboorhood.
Parameters : width : int
The width of the rectangle
height : int
The height of the rectangle
Returns : selem : ndarray
A structuring element consisting only of ones, i.e. every pixel belongs to the neighborhood.
skeletonize¶
- skimage.morphology.skeletonize(image)¶
Return the skeleton of a binary image.
Thinning is used to reduce each connected component in a binary image to a single-pixel wide skeleton.
Parameters : image : numpy.ndarray
A binary image containing the objects to be skeletonized. ‘1’ represents foreground, and ‘0’ represents background. It also accepts arrays of boolean values where True is foreground.
Returns : skeleton : ndarray
A matrix containing the thinned image.
See also
Notes
The algorithm [1] works by making successive passes of the image, removing pixels on object borders. This continues until no more pixels can be removed. The image is correlated with a mask that assigns each pixel a number in the range [0...255] corresponding to each possible pattern of its 8 neighbouring pixels. A look up table is then used to assign the pixels a value of 0, 1, 2 or 3, which are selectively removed during the iterations.
Note that this algorithm will give different results than a medial axis transform, which is also often referred to as “skeletonization”.
References
[R44] A fast parallel algorithm for thinning digital patterns, T. Y. ZHANG and C. Y. SUEN, Communications of the ACM, March 1984, Volume 27, Number 3 Examples
>>> X, Y = np.ogrid[0:9, 0:9] >>> ellipse = (1./3 * (X - 4)**2 + (Y - 4)**2 < 3**2).astype(np.uint8) >>> ellipse array([[0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 0]], dtype=uint8) >>> skel = skeletonize(ellipse) >>> skel array([[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
square¶
- skimage.morphology.square(width, dtype=<type 'numpy.uint8'>)¶
Generates a flat, square-shaped structuring element. Every pixel along the perimeter has a chessboard distance no greater than radius (radius=floor(width/2)) pixels.
Parameters : width : int
The width and height of the square
Returns : selem : ndarray
A structuring element consisting only of ones, i.e. every pixel belongs to the neighborhood.
watershed¶
- skimage.morphology.watershed(image, markers, connectivity=None, offset=None, mask=None)¶
Return a matrix labeled using the watershed segmentation algorithm
Parameters : image: ndarray (2-D, 3-D, ...) of integers :
Data array where the lowest value points are labeled first.
markers: ndarray of the same shape as `image` :
An array marking the basins with the values to be assigned in the label matrix. Zero means not a marker. This array should be of an integer type.
connectivity: ndarray, optional :
An array with the same number of dimensions as image whose non-zero elements indicate neighbors for connection. Following the scipy convention, default is a one-connected array of the dimension of the image.
offset: array_like of shape image.ndim, optional :
offset of the connectivity (one offset per dimension)
mask: ndarray of bools or 0s and 1s, optional :
Array of same shape as image. Only points at which mask == True will be labeled.
Returns : out: ndarray :
A labeled matrix of the same type and shape as markers
See also
- skimage.segmentation.random_walker
- random walker segmentation A segmentation algorithm based on anisotropic diffusion, usually slower than the watershed but with good results on noisy data and boundaries with holes.
Notes
This function implements a watershed algorithm [R45]_that apportions pixels into marked basins. The algorithm uses a priority queue to hold the pixels with the metric for the priority queue being pixel value, then the time of entry into the queue - this settles ties in favor of the closest marker.
Some ideas taken from Soille, “Automated Basin Delineation from Digital Elevation Models Using Mathematical Morphology”, Signal Processing 20 (1990) 171-182
The most important insight in the paper is that entry time onto the queue solves two problems: a pixel should be assigned to the neighbor with the largest gradient or, if there is no gradient, pixels on a plateau should be split between markers on opposite sides.
This implementation converts all arguments to specific, lowest common denominator types, then passes these to a C algorithm.
Markers can be determined manually, or automatically using for example the local minima of the gradient of the image, or the local maxima of the distance function to the background for separating overlapping objects (see example).
References
[R45] http://en.wikipedia.org/wiki/Watershed_%28image_processing%29 [R46] http://cmm.ensmp.fr/~beucher/wtshed.html Examples
The watershed algorithm is very useful to separate overlapping objects
>>> # Generate an initial image with two overlapping circles >>> x, y = np.indices((80, 80)) >>> x1, y1, x2, y2 = 28, 28, 44, 52 >>> r1, r2 = 16, 20 >>> mask_circle1 = (x - x1)**2 + (y - y1)**2 < r1**2 >>> mask_circle2 = (x - x2)**2 + (y - y2)**2 < r2**2 >>> image = np.logical_or(mask_circle1, mask_circle2) >>> # Now we want to separate the two objects in image >>> # Generate the markers as local maxima of the distance >>> # to the background >>> from scipy import ndimage >>> distance = ndimage.distance_transform_edt(image) >>> local_maxi = is_local_maximum(distance, image, np.ones((3, 3))) >>> markers = ndimage.label(local_maxi)[0] >>> labels = watershed(-distance, markers, mask=image)
The algorithm works also for 3-D images, and can be used for example to separate overlapping spheres.
white_tophat¶
- skimage.morphology.white_tophat(image, selem, out=None)¶
Return white top hat of an image.
The white top hat of an image is defined as the image minus its morphological opening. This operation returns the bright spots of the image that are smaller than the structuring element.
Parameters : image : ndarray
Image array.
selem : ndarray
The neighborhood expressed as a 2-D array of 1’s and 0’s.
out : ndarray
The array to store the result of the morphology. If None is passed, a new array will be allocated.
Returns : opening : uint8 array
The result of the morphological white top hat.
Examples
>>> # Subtract grey background from bright peak >>> from skimage.morphology import square >>> bright_on_grey = np.array([[2, 3, 3, 3, 2], ... [3, 4, 5, 4, 3], ... [3, 5, 9, 5, 3], ... [3, 4, 5, 4, 3], ... [2, 3, 3, 3, 2]], dtype=np.uint8) >>> white_tophat(bright_on_grey, square(3)) array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 1, 5, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]], dtype='uint8')