W3cubDocs

/scikit-image

Module: morphology

skimage.morphology.binary_erosion(image[, …]) Return fast binary morphological erosion of an image.
skimage.morphology.binary_dilation(image[, …]) Return fast binary morphological dilation of an image.
skimage.morphology.binary_opening(image[, …]) Return fast binary morphological opening of an image.
skimage.morphology.binary_closing(image[, …]) Return fast binary morphological closing of an image.
skimage.morphology.erosion(image[, selem, …]) Return greyscale morphological erosion of an image.
skimage.morphology.dilation(image[, selem, …]) Return greyscale morphological dilation of an image.
skimage.morphology.opening(image[, selem, out]) Return greyscale morphological opening of an image.
skimage.morphology.closing(image[, selem, out]) Return greyscale morphological closing of an image.
skimage.morphology.white_tophat(image[, …]) Return white top hat of an image.
skimage.morphology.black_tophat(image[, …]) Return black top hat of an image.
skimage.morphology.square(width[, dtype]) Generates a flat, square-shaped structuring element.
skimage.morphology.rectangle(width, height) Generates a flat, rectangular-shaped structuring element.
skimage.morphology.diamond(radius[, dtype]) Generates a flat, diamond-shaped structuring element.
skimage.morphology.disk(radius[, dtype]) Generates a flat, disk-shaped structuring element.
skimage.morphology.cube(width[, dtype]) Generates a cube-shaped structuring element.
skimage.morphology.octahedron(radius[, dtype]) Generates a octahedron-shaped structuring element.
skimage.morphology.ball(radius[, dtype]) Generates a ball-shaped structuring element.
skimage.morphology.octagon(m, n[, dtype]) Generates an octagon shaped structuring element.
skimage.morphology.star(a[, dtype]) Generates a star shaped structuring element.
skimage.morphology.label(input[, neighbors, …]) Label connected regions of an integer array.
skimage.morphology.watershed(image, markers) Find watershed basins in image flooded from given markers.
skimage.morphology.skeletonize(image) Return the skeleton of a binary image.
skimage.morphology.skeletonize_3d(img) Compute the skeleton of a binary image.
skimage.morphology.thin(image[, max_iter]) Perform morphological thinning of a binary image.
skimage.morphology.medial_axis(image[, …]) Compute the medial axis transform of a binary image
skimage.morphology.convex_hull_image(image) Compute the convex hull image of a binary image.
skimage.morphology.convex_hull_object(image) Compute the convex hull image of individual objects in a binary image.
skimage.morphology.reconstruction(seed, mask) Perform a morphological reconstruction of an image.
skimage.morphology.remove_small_objects(ar) Remove connected components smaller than the specified size.
skimage.morphology.remove_small_holes(ar[, …]) Remove continguous holes smaller than the specified size.
skimage.morphology.h_minima(image, h[, selem]) Determine all minima of the image with depth >= h.
skimage.morphology.h_maxima(image, h[, selem]) Determine all maxima of the image with height >= h.
skimage.morphology.local_maxima(image[, selem]) Determine all local maxima of the image.
skimage.morphology.local_minima(image[, selem]) Determine all local minima of the image.

binary_erosion

skimage.morphology.binary_erosion(image, selem=None, out=None) [source]

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.

Parameters:
image : ndarray

Binary input image.

selem : ndarray, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray of bool, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

Returns:
eroded : ndarray of bool or uint

The result of the morphological erosion taking values in [False, True].

binary_dilation

skimage.morphology.binary_dilation(image, selem=None, out=None) [source]

Return fast binary morphological dilation of an image.

This function returns the same result as greyscale dilation but performs faster for binary images.

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

Binary input image.

selem : ndarray, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray of bool, optional

The array to store the result of the morphology. If None, is passed, a new array will be allocated.

Returns:
dilated : ndarray of bool or uint

The result of the morphological dilation with values in [False, True].

binary_opening

skimage.morphology.binary_opening(image, selem=None, out=None) [source]

Return fast binary morphological opening of an image.

This function returns the same result as greyscale opening but performs faster for binary images.

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

Binary input image.

selem : ndarray, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray of bool, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

Returns:
opening : ndarray of bool

The result of the morphological opening.

binary_closing

skimage.morphology.binary_closing(image, selem=None, out=None) [source]

Return fast binary morphological closing of an image.

This function returns the same result as greyscale closing but performs faster for binary images.

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

Binary input image.

selem : ndarray, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray of bool, optional

The array to store the result of the morphology. If None, is passed, a new array will be allocated.

Returns:
closing : ndarray of bool

The result of the morphological closing.

erosion

skimage.morphology.erosion(image, selem=None, out=None, shift_x=False, shift_y=False) [source]

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, optional

The neighborhood expressed as an array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarrays, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

shift_x, shift_y : bool, optional

shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides).

Returns:
eroded : array, same shape as image

The result of the morphological erosion.

Notes

For uint8 (and uint16 up to a certain bit-depth) data, the lower algorithm complexity makes the skimage.filters.rank.minimum function more efficient for larger images and structuring elements.

Examples

>>> # Erosion shrinks bright regions
>>> import numpy as np
>>> 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)

dilation

skimage.morphology.dilation(image, selem=None, out=None, shift_x=False, shift_y=False) [source]

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, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray, optional

The array to store the result of the morphology. If None, is passed, a new array will be allocated.

shift_x, shift_y : bool, optional

shift structuring element about center point. This only affects eccentric structuring elements (i.e. selem with even numbered sides).

Returns:
dilated : uint8 array, same shape and type as image

The result of the morphological dilation.

Notes

For uint8 (and uint16 up to a certain bit-depth) data, the lower algorithm complexity makes the skimage.filters.rank.maximum function more efficient for larger images and structuring elements.

Examples

>>> # Dilation enlarges bright regions
>>> import numpy as np
>>> 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)

opening

skimage.morphology.opening(image, selem=None, out=None) [source]

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, optional

The neighborhood expressed as an array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

Returns:
opening : array, same shape and type as image

The result of the morphological opening.

Examples

>>> # Open up gap between two bright regions (but also shrink regions)
>>> import numpy as np
>>> 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)

closing

skimage.morphology.closing(image, selem=None, out=None) [source]

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, optional

The neighborhood expressed as an array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray, optional

The array to store the result of the morphology. If None, is passed, a new array will be allocated.

Returns:
closing : array, same shape and type as image

The result of the morphological closing.

Examples

>>> # Close a gap between two bright lines
>>> import numpy as np
>>> 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)

white_tophat

skimage.morphology.white_tophat(image, selem=None, out=None) [source]

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, optional

The neighborhood expressed as an array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

Returns:
out : array, same shape and type as image

The result of the morphological white top hat.

Examples

>>> # Subtract grey background from bright peak
>>> import numpy as np
>>> 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)

black_tophat

skimage.morphology.black_tophat(image, selem=None, out=None) [source]

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, optional

The neighborhood expressed as a 2-D array of 1’s and 0’s. If None, use cross-shaped structuring element (connectivity=1).

out : ndarray, optional

The array to store the result of the morphology. If None is passed, a new array will be allocated.

Returns:
out : array, same shape and type as image

The result of the morphological black top hat.

Examples

>>> # Change dark peak to bright peak and subtract background
>>> import numpy as np
>>> 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)

square

skimage.morphology.square(width, dtype=<class 'numpy.uint8'>) [source]

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.

Other Parameters:
dtype : data-type

The data type of the structuring element.

rectangle

skimage.morphology.rectangle(width, height, dtype=<class 'numpy.uint8'>) [source]

Generates a flat, rectangular-shaped structuring element.

Every pixel in the rectangle generated for a given width and given height belongs to the neighborhood.

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.

Other Parameters:
dtype : data-type

The data type of the structuring element.

diamond

skimage.morphology.diamond(radius, dtype=<class 'numpy.uint8'>) [source]

Generates a flat, diamond-shaped structuring element.

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.

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

disk

skimage.morphology.disk(radius, dtype=<class 'numpy.uint8'>) [source]

Generates a flat, disk-shaped structuring element.

A pixel is within the neighborhood if the euclidean distance between it and the origin is no greater than radius.

Parameters:
radius : int

The radius of the disk-shaped structuring element.

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

cube

skimage.morphology.cube(width, dtype=<class 'numpy.uint8'>) [source]

Generates a cube-shaped structuring element.

This is the 3D equivalent of a square. Every pixel along the perimeter has a chessboard distance no greater than radius (radius=floor(width/2)) pixels.

Parameters:
width : int

The width, height and depth of the cube.

Returns:
selem : ndarray

A structuring element consisting only of ones, i.e. every pixel belongs to the neighborhood.

Other Parameters:
dtype : data-type

The data type of the structuring element.

octahedron

skimage.morphology.octahedron(radius, dtype=<class 'numpy.uint8'>) [source]

Generates a octahedron-shaped structuring element.

This is the 3D equivalent of a diamond. 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 octahedron-shaped structuring element.

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

ball

skimage.morphology.ball(radius, dtype=<class 'numpy.uint8'>) [source]

Generates a ball-shaped structuring element.

This is the 3D equivalent of a disk. A pixel is within the neighborhood if the euclidean distance between it and the origin is no greater than radius.

Parameters:
radius : int

The radius of the ball-shaped structuring element.

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

octagon

skimage.morphology.octagon(m, n, dtype=<class 'numpy.uint8'>) [source]

Generates an octagon shaped structuring element.

For a given size of (m) horizontal and vertical sides and a given (n) height or width of slanted sides octagon is generated. The slanted sides are 45 or 135 degrees to the horizontal axis and hence the widths and heights are equal.

Parameters:
m : int

The size of the horizontal and vertical sides.

n : int

The height or width of the slanted sides.

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

star

skimage.morphology.star(a, dtype=<class 'numpy.uint8'>) [source]

Generates a star shaped structuring element.

Start has 8 vertices and is an overlap of square of size 2*a + 1 with its 45 degree rotated version. The slanted sides are 45 or 135 degrees to the horizontal axis.

Parameters:
a : int

Parameter deciding the size of the star structural element. The side of the square array returned is 2*a + 1 + 2*floor(a / 2).

Returns:
selem : ndarray

The structuring element where elements of the neighborhood are 1 and 0 otherwise.

Other Parameters:
dtype : data-type

The data type of the structuring element.

label

skimage.morphology.label(input, neighbors=None, background=None, return_num=False, connectivity=None) [source]

Label connected regions of an integer array.

Two pixels are connected when they are neighbors and have the same value. In 2D, they can be neighbors either in a 1- or 2-connected sense. The value refers to the maximum number of orthogonal hops to consider a pixel/voxel a neighbor:

1-connectivity      2-connectivity     diagonal connection close-up

     [ ]           [ ]  [ ]  [ ]         [ ]
      |               \  |  /             |  <- hop 2
[ ]--[x]--[ ]      [ ]--[x]--[ ]    [x]--[ ]
      |               /  |  \         hop 1
     [ ]           [ ]  [ ]  [ ]
Parameters:
input : ndarray of dtype int

Image to label.

neighbors : {4, 8}, int, optional

Whether to use 4- or 8-“connectivity”. In 3D, 4-“connectivity” means connected pixels have to share face, whereas with 8-“connectivity”, they have to share only edge or vertex. Deprecated, use ``connectivity`` instead.

background : int, optional

Consider all pixels with this value as background pixels, and label them as 0. By default, 0-valued pixels are considered as background pixels.

return_num : bool, optional

Whether to return the number of assigned labels.

connectivity : int, optional

Maximum number of orthogonal hops to consider a pixel/voxel as a neighbor. Accepted values are ranging from 1 to input.ndim. If None, a full connectivity of input.ndim is used.

Returns:
labels : ndarray of dtype int

Labeled array, where all connected regions are assigned the same integer value.

num : int, optional

Number of labels, which equals the maximum label index and is only returned if return_num is True.

See also

regionprops

References

[1] Christophe Fiorio and Jens Gustedt, “Two linear time Union-Find strategies for image processing”, Theoretical Computer Science 154 (1996), pp. 165-181.
[2] Kensheng Wu, Ekow Otoo and Arie Shoshani, “Optimizing connected component labeling algorithms”, Paper LBNL-56864, 2005, Lawrence Berkeley National Laboratory (University of California), http://repositories.cdlib.org/lbnl/LBNL-56864

Examples

>>> import numpy as np
>>> x = np.eye(3).astype(int)
>>> print(x)
[[1 0 0]
 [0 1 0]
 [0 0 1]]
>>> print(label(x, connectivity=1))
[[1 0 0]
 [0 2 0]
 [0 0 3]]
>>> print(label(x, connectivity=2))
[[1 0 0]
 [0 1 0]
 [0 0 1]]
>>> print(label(x, background=-1))
[[1 2 2]
 [2 1 2]
 [2 2 1]]
>>> x = np.array([[1, 0, 0],
...               [1, 1, 5],
...               [0, 0, 0]])
>>> print(label(x))
[[1 0 0]
 [1 1 2]
 [0 0 0]]

watershed

skimage.morphology.watershed(image, markers, connectivity=1, offset=None, mask=None, compactness=0, watershed_line=False) [source]

Find watershed basins in image flooded from given markers.

Parameters:
image: ndarray (2-D, 3-D, …) of integers

Data array where the lowest value points are labeled first.

markers: int, or ndarray of int, same shape as `image`

The desired number of markers, or an array marking the basins with the values to be assigned in the label matrix. Zero means not a marker.

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.

compactness : float, optional

Use compact watershed [3] with given compactness parameter. Higher values result in more regularly-shaped watershed basins.

watershed_line : bool, optional

If watershed_line is True, a one-pixel wide line separates the regions obtained by the watershed algorithm. The line has the label 0.

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 [1] [2] 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

[1] (1, 2) http://en.wikipedia.org/wiki/Watershed_%28image_processing%29
[2] (1, 2) http://cmm.ensmp.fr/~beucher/wtshed.html
[3] (1, 2) Peer Neubert & Peter Protzel (2014). Compact Watershed and Preemptive SLIC: On Improving Trade-offs of Superpixel Segmentation Algorithms. ICPR 2014, pp 996-1001. DOI:10.1109/ICPR.2014.181 https://www.tu-chemnitz.de/etit/proaut/forschung/rsrc/cws_pSLIC_ICPR.pdf

Examples

The watershed algorithm is useful to separate overlapping objects.

We first 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)

Next, we want to separate the two circles. We generate markers at the maxima of the distance to the background:

>>> from scipy import ndimage as ndi
>>> distance = ndi.distance_transform_edt(image)
>>> from skimage.feature import peak_local_max
>>> local_maxi = peak_local_max(distance, labels=image,
...                             footprint=np.ones((3, 3)),
...                             indices=False)
>>> markers = ndi.label(local_maxi)[0]

Finally, we run the watershed on the image and markers:

>>> labels = watershed(-distance, markers, mask=image)

The algorithm works also for 3-D images, and can be used for example to separate overlapping spheres.

skeletonize

skimage.morphology.skeletonize(image) [source]

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

medial_axis

Notes

The algorithm [Zha84] 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

[Zha84] (1, 2) 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.astype(np.uint8)
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)

skeletonize_3d

skimage.morphology.skeletonize_3d(img) [source]

Compute 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:
img : ndarray, 2D or 3D

A binary image containing the objects to be skeletonized. Zeros represent background, nonzero values are foreground.

Returns:
skeleton : ndarray

The thinned image.

Notes

The method of [Lee94] uses an octree data structure to examine a 3x3x3 neighborhood of a pixel. The algorithm proceeds by iteratively sweeping over the image, and removing pixels at each iteration until the image stops changing. Each iteration consists of two steps: first, a list of candidates for removal is assembled; then pixels from this list are rechecked sequentially, to better preserve connectivity of the image.

The algorithm this function implements is different from the algorithms used by either skeletonize or medial_axis, thus for 2D images the results produced by this function are generally different.

References

[Lee94] (1, 2) T.-C. Lee, R.L. Kashyap and C.-N. Chu, Building skeleton models via 3-D medial surface/axis thinning algorithms. Computer Vision, Graphics, and Image Processing, 56(6):462-478, 1994.

thin

skimage.morphology.thin(image, max_iter=None) [source]

Perform morphological thinning of a binary image.

Parameters:
image : binary (M, N) ndarray

The image to be thinned.

max_iter : int, number of iterations, optional

Regardless of the value of this parameter, the thinned image is returned immediately if an iteration produces no change. If this parameter is specified it thus sets an upper bound on the number of iterations performed.

Returns:
out : ndarray of bool

Thinned image.

Notes

This algorithm [1] works by making multiple passes over the image, removing pixels matching a set of criteria designed to thin connected regions while preserving eight-connected components and 2 x 2 squares [2]. In each of the two sub-iterations the algorithm correlates the intermediate skeleton image with a neighborhood mask, then looks up each neighborhood in a lookup table indicating whether the central pixel should be deleted in that sub-iteration.

References

[1] (1, 2) Z. Guo and R. W. Hall, “Parallel thinning with two-subiteration algorithms,” Comm. ACM, vol. 32, no. 3, pp. 359-373, 1989. DOI:10.1145/62065.62074
[2] (1, 2) Lam, L., Seong-Whan Lee, and Ching Y. Suen, “Thinning Methodologies-A Comprehensive Survey,” IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol 14, No. 9, p. 879, 1992. DOI:10.1109/34.161346

Examples

>>> square = np.zeros((7, 7), dtype=np.uint8)
>>> square[1:-1, 2:-2] = 1
>>> square[0, 1] =  1
>>> square
array([[0, 1, 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)
>>> skel = thin(square)
>>> skel.astype(np.uint8)
array([[0, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 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, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

medial_axis

skimage.morphology.medial_axis(image, mask=None, return_distance=False) [source]

Compute the medial axis transform of a binary image

Parameters:
image : binary ndarray, shape (M, N)

The image of the shape to be skeletonized.

mask : binary ndarray, shape (M, N), optional

If a mask is given, only those elements in image 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, optional

Distance transform of the image (only returned if return_distance is True)

See also

skeletonize

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)
>>> 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)

convex_hull_image

skimage.morphology.convex_hull_image(image, offset_coordinates=True, tolerance=1e-10) [source]

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 : array

Binary input image. This array is cast to bool before processing.

offset_coordinates : bool, optional

If True, a pixel at coordinate, e.g., (4, 7) will be represented by coordinates (3.5, 7), (4.5, 7), (4, 6.5), and (4, 7.5). This adds some “extent” to a pixel when computing the hull.

tolerance : float, optional

Tolerance when determining whether a point is inside the hull. Due to numerical floating point errors, a tolerance of 0 can result in some points erroneously being classified as being outside the hull.

Returns:
hull : (M, N) array of bool

Binary image with pixels in convex hull set to True.

References

[1] http://blogs.mathworks.com/steve/2011/10/04/binary-image-convex-hull-algorithm-notes/

convex_hull_object

skimage.morphology.convex_hull_object(image, neighbors=8) [source]

Compute the convex hull image of individual objects in 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 : (M, N) array

Binary input image.

neighbors : {4, 8}, int

Whether to use 4- or 8-connectivity.

Returns:
hull : ndarray of bool

Binary image with pixels in convex hull set to True.

Notes

This function uses skimage.morphology.label to define unique objects, finds the convex hull of each using convex_hull_image, and combines these regions with logical OR. Be aware the convex hulls of unconnected objects may overlap in the result. If this is suspected, consider using convex_hull_image separately on each object.

reconstruction

skimage.morphology.reconstruction(seed, mask, method='dilation', selem=None, offset=None) [source]

Perform a morphological reconstruction of an image.

Morphological reconstruction by dilation is similar to basic morphological dilation: high-intensity values will replace nearby low-intensity values. The basic dilation operator, however, uses a structuring element to determine how far a value in the input image can spread. In contrast, reconstruction uses two images: a “seed” image, which specifies the values that spread, and a “mask” image, which gives the maximum allowed value at each pixel. The mask image, like the structuring element, limits the spread of high-intensity values. Reconstruction by erosion is simply the inverse: low-intensity values spread from the seed image and are limited by the mask image, which represents the minimum allowed value.

Alternatively, you can think of reconstruction as a way to isolate the connected regions of an image. For dilation, reconstruction connects regions marked by local maxima in the seed image: neighboring pixels less-than-or-equal-to those seeds are connected to the seeded region. Local maxima with values larger than the seed image will get truncated to the seed value.

Parameters:
seed : ndarray

The seed image (a.k.a. marker image), which specifies the values that are dilated or eroded.

mask : ndarray

The maximum (dilation) / minimum (erosion) allowed value at each pixel.

method : {‘dilation’|’erosion’}

Perform reconstruction by dilation or erosion. In dilation (or erosion), the seed image is dilated (or eroded) until limited by the mask image. For dilation, each seed value must be less than or equal to the corresponding mask value; for erosion, the reverse is true.

selem : ndarray

The neighborhood expressed as an n-D array of 1’s and 0’s. Default is the ball of radius 1 according to the maximum norm (i.e. a 3x3 square for 2D images, a 3x3x3 cube for 3D images, etc.)

Returns:
reconstructed : ndarray

The result of morphological reconstruction.

Notes

The algorithm is taken from [1]. Applications for greyscale reconstruction are discussed in [2] and [3].

References

[1] (1, 2) Robinson, “Efficient morphological reconstruction: a downhill filter”, Pattern Recognition Letters 25 (2004) 1759-1767.
[2] (1, 2) Vincent, L., “Morphological Grayscale Reconstruction in Image Analysis: Applications and Efficient Algorithms”, IEEE Transactions on Image Processing (1993)
[3] (1, 2) Soille, P., “Morphological Image Analysis: Principles and Applications”, Chapter 6, 2nd edition (2003), ISBN 3540429883.

Examples

>>> import numpy as np
>>> from skimage.morphology import reconstruction

First, we create a sinusoidal mask image with peaks at middle and ends.

>>> x = np.linspace(0, 4 * np.pi)
>>> y_mask = np.cos(x)

Then, we create a seed image initialized to the minimum mask value (for reconstruction by dilation, min-intensity values don’t spread) and add “seeds” to the left and right peak, but at a fraction of peak value (1).

>>> y_seed = y_mask.min() * np.ones_like(x)
>>> y_seed[0] = 0.5
>>> y_seed[-1] = 0
>>> y_rec = reconstruction(y_seed, y_mask)

The reconstructed image (or curve, in this case) is exactly the same as the mask image, except that the peaks are truncated to 0.5 and 0. The middle peak disappears completely: Since there were no seed values in this peak region, its reconstructed value is truncated to the surrounding value (-1).

As a more practical example, we try to extract the bright features of an image by subtracting a background image created by reconstruction.

>>> y, x = np.mgrid[:20:0.5, :20:0.5]
>>> bumps = np.sin(x) + np.sin(y)

To create the background image, set the mask image to the original image, and the seed image to the original image with an intensity offset, h.

>>> h = 0.3
>>> seed = bumps - h
>>> background = reconstruction(seed, bumps)

The resulting reconstructed image looks exactly like the original image, but with the peaks of the bumps cut off. Subtracting this reconstructed image from the original image leaves just the peaks of the bumps

>>> hdome = bumps - background

This operation is known as the h-dome of the image and leaves features of height h in the subtracted image.

remove_small_objects

skimage.morphology.remove_small_objects(ar, min_size=64, connectivity=1, in_place=False) [source]

Remove connected components smaller than the specified size.

Parameters:
ar : ndarray (arbitrary shape, int or bool type)

The array containing the connected components of interest. If the array type is int, it is assumed that it contains already-labeled objects. The ints must be non-negative.

min_size : int, optional (default: 64)

The smallest allowable connected component size.

connectivity : int, {1, 2, …, ar.ndim}, optional (default: 1)

The connectivity defining the neighborhood of a pixel.

in_place : bool, optional (default: False)

If True, remove the connected components in the input array itself. Otherwise, make a copy.

Returns:
out : ndarray, same shape and type as input ar

The input array with small connected components removed.

Raises:
TypeError

If the input array is of an invalid type, such as float or string.

ValueError

If the input array contains negative values.

Examples

>>> from skimage import morphology
>>> a = np.array([[0, 0, 0, 1, 0],
...               [1, 1, 1, 0, 0],
...               [1, 1, 1, 0, 1]], bool)
>>> b = morphology.remove_small_objects(a, 6)
>>> b
array([[False, False, False, False, False],
       [ True,  True,  True, False, False],
       [ True,  True,  True, False, False]], dtype=bool)
>>> c = morphology.remove_small_objects(a, 7, connectivity=2)
>>> c
array([[False, False, False,  True, False],
       [ True,  True,  True, False, False],
       [ True,  True,  True, False, False]], dtype=bool)
>>> d = morphology.remove_small_objects(a, 6, in_place=True)
>>> d is a
True

remove_small_holes

skimage.morphology.remove_small_holes(ar, area_threshold=64, connectivity=1, in_place=False, min_size=None) [source]

Remove continguous holes smaller than the specified size.

Parameters:
ar : ndarray (arbitrary shape, int or bool type)

The array containing the connected components of interest.

area_threshold : int, optional (default: 64)

The maximum area, in pixels, of a contiguous hole that will be filled. Replaces min_size.

connectivity : int, {1, 2, …, ar.ndim}, optional (default: 1)

The connectivity defining the neighborhood of a pixel.

in_place : bool, optional (default: False)

If True, remove the connected components in the input array itself. Otherwise, make a copy.

Returns:
out : ndarray, same shape and type as input ar

The input array with small holes within connected components removed.

Raises:
TypeError

If the input array is of an invalid type, such as float or string.

ValueError

If the input array contains negative values.

Notes

If the array type is int, it is assumed that it contains already-labeled objects. The labels are not kept in the output image (this function always outputs a bool image). It is suggested that labeling is completed after using this function.

Examples

>>> from skimage import morphology
>>> a = np.array([[1, 1, 1, 1, 1, 0],
...               [1, 1, 1, 0, 1, 0],
...               [1, 0, 0, 1, 1, 0],
...               [1, 1, 1, 1, 1, 0]], bool)
>>> b = morphology.remove_small_holes(a, 2)
>>> b
array([[ True,  True,  True,  True,  True, False],
       [ True,  True,  True,  True,  True, False],
       [ True, False, False,  True,  True, False],
       [ True,  True,  True,  True,  True, False]], dtype=bool)
>>> c = morphology.remove_small_holes(a, 2, connectivity=2)
>>> c
array([[ True,  True,  True,  True,  True, False],
       [ True,  True,  True, False,  True, False],
       [ True, False, False,  True,  True, False],
       [ True,  True,  True,  True,  True, False]], dtype=bool)
>>> d = morphology.remove_small_holes(a, 2, in_place=True)
>>> d is a
True

h_minima

skimage.morphology.h_minima(image, h, selem=None) [source]

Determine all minima of the image with depth >= h.

The local minima are defined as connected sets of pixels with equal grey level strictly smaller than the grey levels of all pixels in direct neighborhood of the set.

A local minimum M of depth h is a local minimum for which there is at least one path joining M with a deeper minimum on which the maximal value is f(M) + h (i.e. the values along the path are not increasing by more than h with respect to the minimum’s value) and no path for which the maximal value is smaller.

Parameters:
image : ndarray

The input image for which the minima are to be calculated.

h : unsigned integer

The minimal depth of all extracted minima.

selem : ndarray, optional

The neighborhood expressed as an n-D array of 1’s and 0’s. Default is the ball of radius 1 according to the maximum norm (i.e. a 3x3 square for 2D images, a 3x3x3 cube for 3D images, etc.)

Returns:
h_min : ndarray

The minima of depth >= h. The result image is a binary image, where pixels belonging to the selected minima take value 1, the other pixels take value 0.

See also

skimage.morphology.extrema.h_maxima, skimage.morphology.extrema.local_maxima, skimage.morphology.extrema.local_minima

References

[1] Soille, P., “Morphological Image Analysis: Principles and Applications” (Chapter 6), 2nd edition (2003), ISBN 3540429883.

Examples

>>> import numpy as np
>>> from skimage.morphology import extrema

We create an image (quadratic function with a minimum in the center and 4 additional constant maxima. The depth of the minima are: 1, 21, 41, 61, 81, 101

>>> w = 10
>>> x, y = np.mgrid[0:w,0:w]
>>> f = 180 + 0.2*((x - w/2)**2 + (y-w/2)**2)
>>> f[2:4,2:4] = 160; f[2:4,7:9] = 140; f[7:9,2:4] = 120; f[7:9,7:9] = 100
>>> f = f.astype(np.int)

We can calculate all minima with a depth of at least 40:

>>> minima = extrema.h_minima(f, 40)

The resulting image will contain 4 local minima.

h_maxima

skimage.morphology.h_maxima(image, h, selem=None) [source]

Determine all maxima of the image with height >= h.

The local maxima are defined as connected sets of pixels with equal grey level strictly greater than the grey level of all pixels in direct neighborhood of the set.

A local maximum M of height h is a local maximum for which there is at least one path joining M with a higher maximum on which the minimal value is f(M) - h (i.e. the values along the path are not decreasing by more than h with respect to the maximum’s value) and no path for which the minimal value is greater.

Parameters:
image : ndarray

The input image for which the maxima are to be calculated.

h : unsigned integer

The minimal height of all extracted maxima.

selem : ndarray, optional

The neighborhood expressed as an n-D array of 1’s and 0’s. Default is the ball of radius 1 according to the maximum norm (i.e. a 3x3 square for 2D images, a 3x3x3 cube for 3D images, etc.)

Returns:
h_max : ndarray

The maxima of height >= h. The result image is a binary image, where pixels belonging to the selected maxima take value 1, the others take value 0.

See also

skimage.morphology.extrema.h_minima, skimage.morphology.extrema.local_maxima, skimage.morphology.extrema.local_minima

References

[1] Soille, P., “Morphological Image Analysis: Principles and Applications” (Chapter 6), 2nd edition (2003), ISBN 3540429883.

Examples

>>> import numpy as np
>>> from skimage.morphology import extrema

We create an image (quadratic function with a maximum in the center and 4 additional constant maxima. The heights of the maxima are: 1, 21, 41, 61, 81, 101

>>> w = 10
>>> x, y = np.mgrid[0:w,0:w]
>>> f = 20 - 0.2*((x - w/2)**2 + (y-w/2)**2)
>>> f[2:4,2:4] = 40; f[2:4,7:9] = 60; f[7:9,2:4] = 80; f[7:9,7:9] = 100
>>> f = f.astype(np.int)

We can calculate all maxima with a height of at least 40:

>>> maxima = extrema.h_maxima(f, 40)

The resulting image will contain 4 local maxima.

local_maxima

skimage.morphology.local_maxima(image, selem=None) [source]

Determine all local maxima of the image.

The local maxima are defined as connected sets of pixels with equal grey level strictly greater than the grey levels of all pixels in direct neighborhood of the set.

For integer typed images, this corresponds to the h-maxima with h=1. For float typed images, h is determined as the smallest difference between grey levels.

Parameters:
image : ndarray

The input image for which the maxima are to be calculated.

selem : ndarray, optional

The neighborhood expressed as an n-D array of 1’s and 0’s. Default is the ball of radius 1 according to the maximum norm (i.e. a 3x3 square for 2D images, a 3x3x3 cube for 3D images, etc.)

Returns:
local_max : ndarray

All local maxima of the image. The result image is a binary image, where pixels belonging to local maxima take value 1, the other pixels take value 0.

See also

skimage.morphology.extrema.h_minima, skimage.morphology.extrema.h_maxima, skimage.morphology.extrema.local_minima

References

[1] Soille, P., “Morphological Image Analysis: Principles and Applications” (Chapter 6), 2nd edition (2003), ISBN 3540429883.

Examples

>>> import numpy as np
>>> from skimage.morphology import extrema

We create an image (quadratic function with a maximum in the center and 4 additional constant maxima. The heights of the maxima are: 1, 21, 41, 61, 81, 101

>>> w = 10
>>> x, y = np.mgrid[0:w,0:w]
>>> f = 20 - 0.2*((x - w/2)**2 + (y-w/2)**2)
>>> f[2:4,2:4] = 40; f[2:4,7:9] = 60; f[7:9,2:4] = 80; f[7:9,7:9] = 100
>>> f = f.astype(np.int)

We can calculate all local maxima:

>>> maxima = extrema.local_maxima(f)

The resulting image will contain all 6 local maxima.

local_minima

skimage.morphology.local_minima(image, selem=None) [source]

Determine all local minima of the image.

The local minima are defined as connected sets of pixels with equal grey level strictly smaller than the grey levels of all pixels in direct neighborhood of the set.

For integer typed images, this corresponds to the h-minima with h=1. For float typed images, h is determined as the smallest difference between grey levels.

Parameters:
image : ndarray

The input image for which the minima are to be calculated.

selem : ndarray, optional

The neighborhood expressed as an n-D array of 1’s and 0’s. Default is the ball of radius 1 according to the maximum norm (i.e. a 3x3 square for 2D images, a 3x3x3 cube for 3D images, etc.)

Returns:
local_min : ndarray

All local minima of the image. The result image is a binary image, where pixels belonging to local minima take value 1, the other pixels take value 0.

See also

skimage.morphology.extrema.h_minima, skimage.morphology.extrema.h_maxima, skimage.morphology.extrema.local_maxima

References

[1] Soille, P., “Morphological Image Analysis: Principles and Applications” (Chapter 6), 2nd edition (2003), ISBN 3540429883.

Examples

>>> import numpy as np
>>> from skimage.morphology import extrema

We create an image (quadratic function with a minimum in the center and 4 additional constant maxima. The depth of the minima are: 1, 21, 41, 61, 81, 101

>>> w = 10
>>> x, y = np.mgrid[0:w,0:w]
>>> f = 180 + 0.2*((x - w/2)**2 + (y-w/2)**2)
>>> f[2:4,2:4] = 160; f[2:4,7:9] = 140; f[7:9,2:4] = 120; f[7:9,7:9] = 100
>>> f = f.astype(np.int)

We can calculate all local minima:

>>> minima = extrema.local_minima(f)

The resulting image will contain all 6 local minima.

© 2011 the scikit-image team
Licensed under the BSD 3-clause License.
http://scikit-image.org/docs/0.14.x/api/skimage.morphology.html