Source code for histolab.filters.morphological_filters_functional

# encoding: utf-8

# ------------------------------------------------------------------------
# Copyright 2022 All Histolab Contributors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------------------

import numpy as np
import scipy.ndimage as sc_ndimage
import skimage.feature as sk_feature
import skimage.morphology as sk_morphology
import skimage.segmentation as sk_segmentation

from .util import mask_percent

[docs]def remove_small_objects( np_mask: np.ndarray, min_size: int = 3000, avoid_overmask: bool = True, overmask_thresh: int = 95, ) -> np.ndarray: """Remove connected components which size is less than min_size. is True, this function can recursively call itself with progressively to avoid removing too many objects in the mask. Parameters ---------- np_img : np.ndarray (arbitrary shape, int or bool type) Input mask min_size : int, optional Minimum size of small object to remove. Default is 3000 avoid_overmask : bool, optional (default is True) If True, avoid masking above the overmask_thresh percentage. overmask_thresh : int, optional (default is 95) If avoid_overmask is True, avoid masking above this threshold percentage value. Returns ------- np.ndarray Mask with small objects filtered out """ mask_no_small_object = sk_morphology.remove_small_objects(np_mask, min_size) if ( avoid_overmask and mask_percent(mask_no_small_object) >= overmask_thresh and min_size >= 1 ): new_min_size = min_size // 2 mask_no_small_object = remove_small_objects( np_mask, new_min_size, avoid_overmask, overmask_thresh ) return mask_no_small_object
[docs]def watershed_segmentation(np_mask: np.ndarray, region_shape: int = 6) -> np.ndarray: """Segment and label a binary mask with Watershed segmentation [1]_ The watershed algorithm treats pixels values as a local topography (elevation). Parameters ---------- np_mask : np.ndarray Input mask region_shape : int, optional The local region within which to search for image peaks is defined as a squared area region_shape x region_shape. Default is 6. Returns ------- np.ndarray Labelled segmentation mask References -------- .. [1] Watershed segmentation. """ distance = sc_ndimage.distance_transform_edt(np_mask) peak_idx = sk_feature.peak_local_max( distance, footprint=np.ones((region_shape, region_shape)), labels=np_mask, ) peak_mask = np.zeros_like(np_mask, dtype=bool) peak_mask[tuple(peak_idx.T)] = True markers = sc_ndimage.label(peak_mask)[0] labels = sk_segmentation.watershed(-distance, markers, mask=np_mask) return labels