morphsnakes - Morphsnakes segmentation

Morphological snakes algorithm for 3D image segmentation. Source: https://github.com/pmneila/morphsnakes

LICENSE

Copyright (c) 2013-2015, P. M. Neila All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Morphological Snakes

Morphological Snakes [1]_ are a family of methods for image segmentation. Their behavior is similar to that of active contours (for example, Geodesic Active Contours [2]_ or Active Contours without Edges [3]_). However, Morphological Snakes use morphological operators (such as dilation or erosion) over a binary array instead of solving PDEs over a floating point array, which is the standard approach for active contours. This makes Morphological Snakes faster and numerically more stable than their traditional counterpart.

There are two Morphological Snakes methods available in this implementation: Morphological Geodesic Active Contours (MorphGAC, implemented in the function morphological_geodesic_active_contour) and Morphological Active Contours without Edges (MorphACWE, implemented in the function morphological_chan_vese).

MorphGAC is suitable for images with visible contours, even when these contours might be noisy, cluttered, or partially unclear. It requires, however, that the image is preprocessed to highlight the contours. This can be done using the function inverse_gaussian_gradient, although the user might want to define their own version. The quality of the MorphGAC segmentation depends greatly on this preprocessing step.

On the contrary, MorphACWE works well when the pixel values of the inside and the outside regions of the object to segment have different averages. Unlike MorphGAC, MorphACWE does not require that the contours of the object are well defined, and it works over the original image without any preceding processing. This makes MorphACWE easier to use and tune than MorphGAC.

References

[1] A Morphological Approach to Curvature-based Evolution of Curves and Surfaces, Pablo Márquez-Neila, Luis Baumela and Luis Álvarez. In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI), 2014, DOI 10.1109/TPAMI.2013.106

[2] Geodesic Active Contours, Vicent Caselles, Ron Kimmel and Guillermo Sapiro. In International Journal of Computer Vision (IJCV), 1997, DOI:10.1023/A:1007979827043

[3] Active Contours without Edges, Tony Chan and Luminita Vese. In IEEE Transactions on Image Processing, 2001, DOI:10.1109/83.902291

/Users/nc1333/miniforge3/envs/blender_tissue_cartography/lib/python3.11/site-packages/fastcore/docscrape.py:259: UserWarning: Unknown section See Also
  else: warn(msg)

morphological_geodesic_active_contour


def morphological_geodesic_active_contour(
    gimage, # Preprocessed image or volume to be segmented. This is very rarely the
original image. Instead, this is usually a preprocessed version of the
original image that enhances and highlights the borders (or other
structures) of the object to segment.
`morphological_geodesic_active_contour` will try to stop the contour
evolution in areas where `gimage` is small. See
`morphsnakes.inverse_gaussian_gradient` as an example function to
perform this preprocessing. Note that the quality of
`morphological_geodesic_active_contour` might greatly depend on this
preprocessing.
    iterations, # Number of iterations to run.
    init_level_set:str='circle', # Initial level set. If an array is given, it will be binarized and used
as the initial level set. If a string is given, it defines the method
to generate a reasonable initial level set with the shape of the
`image`. Accepted values are 'checkerboard' and 'circle'. See the
documentation of `checkerboard_level_set` and `circle_level_set`
respectively for details about how these level sets are created.
    smoothing:int=1, # Number of times the smoothing operator is applied per iteration.
Reasonable values are around 1-4. Larger values lead to smoother
segmentations.
    threshold:str='auto', # Areas of the image with a value smaller than this threshold will be
considered borders. The evolution of the contour will stop in this
areas.
    balloon:int=0, # Balloon force to guide the contour in non-informative areas of the
image, i.e., areas where the gradient of the image is too small to push
the contour towards a border. A negative value will shrink the contour,
while a positive value will expand the contour in these areas. Setting
this to zero will disable the balloon force.
    iter_callback:function=<lambda>, # If given, this function is called once per iteration with the current
level set as the only argument. This is useful for debugging or for
plotting intermediate results during the evolution.
): # Final segmentation (i.e., the final level set)

Morphological Geodesic Active Contours (MorphGAC).

Geodesic active contours implemented with morphological operators. It can be used to segment objects with visible but noisy, cluttered, broken borders.


morphological_chan_vese


def morphological_chan_vese(
    image, # Grayscale image or volume to be segmented.
    iterations, # Number of iterations to run
    init_level_set:str='checkerboard', # Initial level set. If an array is given, it will be binarized and used
as the initial level set. If a string is given, it defines the method
to generate a reasonable initial level set with the shape of the
`image`. Accepted values are 'checkerboard' and 'circle'. See the
documentation of `checkerboard_level_set` and `circle_level_set`
respectively for details about how these level sets are created.
    smoothing:int=1, # Number of times the smoothing operator is applied per iteration.
Reasonable values are around 1-4. Larger values lead to smoother
segmentations.
    lambda1:int=1, # Weight parameter for the outer region. If `lambda1` is larger than
`lambda2`, the outer region will contain a larger range of values than
the inner region.
    lambda2:int=1, # Weight parameter for the inner region. If `lambda2` is larger than
`lambda1`, the inner region will contain a larger range of values than
the outer region.
    iter_callback:function=<lambda>, # If given, this function is called once per iteration with the current
level set as the only argument. This is useful for debugging or for
plotting intermediate results during the evolution.
): # Final segmentation (i.e., the final level set)

Morphological Active Contours without Edges (MorphACWE)

Active contours without edges implemented with morphological operators. It can be used to segment objects in images and volumes without well defined borders. It is required that the inside of the object looks different on average than the outside (i.e., the inner area of the object should be darker or lighter than the outer area on average).


inverse_gaussian_gradient


def inverse_gaussian_gradient(
    image, # Grayscale image or volume.
    alpha:float=100.0, # Controls the steepness of the inversion. A larger value will make the
transition between the flat areas and border areas steeper in the
resulting array.
    sigma:float=5.0, # Standard deviation of the Gaussian filter applied over the image.
): # Preprocessed image (or volume) suitable for
`morphological_geodesic_active_contour`.

Inverse of gradient magnitude.

Compute the magnitude of the gradients in the image and then inverts the result in the range [0, 1]. Flat areas are assigned values close to 1, while areas close to borders are assigned values close to 0.

This function or a similar one defined by the user should be applied over the image as a preprocessing step before calling morphological_geodesic_active_contour.


checkerboard_level_set


def checkerboard_level_set(
    image_shape, # Shape of the image.
    square_size:int=5, # Size of the squares of the checkerboard. It defaults to 5.
): # Binary level set of the checkerboard.

Create a checkerboard level set with binary values.


ellipsoid_level_set


def ellipsoid_level_set(
    image_shape, # Shape of the image
    center:NoneType=None, # Coordinates of the center of the ellipsoid.
If not given, it defaults to the center of the image.
    semi_axis:NoneType=None, # Lengths of the semi-axis of the ellispoid.
If not given, it defaults to the half of the image dimensions.
): # Binary level set of the ellipsoid with the given `center`
and `semi_axis`.

Create a ellipsoid level set with binary values.


circle_level_set


def circle_level_set(
    image_shape, # Shape of the image
    center:NoneType=None, # Coordinates of the center of the circle given in (row, column). If not
given, it defaults to the center of the image.
    radius:NoneType=None, # Radius of the circle. If not given, it is set to the 75% of the
smallest image dimension.
): # Binary level set of the circle with the given `radius` and `center`.

Create a circle level set with binary values.


inf_sup


def inf_sup(
    u
):

IS operator.


sup_inf


def sup_inf(
    u
):

SI operator.