import numpy as np
[docs]
def compact(im_label, compaction=3):
"""Performs a thinning operation on a label image to remove thin
protrusions from objects that are in contact with the background. Applies a
distance transform and sequentially removes pixels with small distances to
background that are not connected to higher distance pixels.
Parameters
----------
im_label : array_like
A labeled segmentation mask
compaction : int
Factor used in compacting objects to remove thin protrusions. Referred
to as d in the reference below. Default value = 3.
Notes
-----
Implemented from the reference below.
Returns
-------
im_compact : array_like
A labeled segmentation mask with thin protrusions removed.
See Also
--------
histomicstk.segmentation.label.area_open,
histomicstk.segmentation.label.condense,
histomicstk.segmentation.label.shuffle,
histomicstk.segmentation.label.split,
histomicstk.segmentation.label.width_open
References
----------
.. [#] S. Weinert et al "Detection and Segmentation of Cell Nuclei in
Virtual Microscopy Images: A Minimum-Model Approach" in Nature
Scientific Reports,vol.2,no.503, doi:10.1038/srep00503, 2012.
"""
import scipy.ndimage as ndi
# copy input image
im_compact = im_label.copy()
# generate distance map of label image
D = ndi.distance_transform_cdt(im_compact > 0, metric='taxicab')
# define 4-neighbors filtering kernel
Kernel = np.zeros((3, 3), dtype=bool)
Kernel[1, :] = True
Kernel[:, 1] = True
# sweep over distance values from d-1 to 1
for i in np.arange(compaction - 1, 0, -1):
# four-neighbor maxima of distance transform
MaxD = ndi.maximum_filter(D, footprint=Kernel)
# identify pixels whose max 4-neighbor is less than i+1
Decrement = (D == i) & (MaxD < i + 1)
# decrement non-compact pixels
D[Decrement] -= 1
# zero label pixels where D == 0
im_compact[D == 0] = 0
return im_compact