Source code for pyfibre.model.tools.utilities

"""
PyFibre
Image Segmentation Library

Created by: Frank Longford
Created on: 18/02/2019

Last Modified: 18/02/2019
"""

import logging
import numpy as np

from scipy.ndimage.filters import gaussian_filter
from scipy.ndimage.morphology import binary_dilation

from skimage import measure
from skimage.morphology import remove_small_objects, remove_small_holes

logger = logging.getLogger(__name__)


[docs]def smooth_binary(binary, sigma=None): """Smooths binary image based on Guassian filter with sigma standard deviation""" if sigma is not None: smoothed = gaussian_filter( binary.astype(float), sigma=sigma ) # Convert float image back to binary binary = np.where(smoothed, 1, 0) return binary
[docs]def region_check(region, min_size=0, min_frac=0, edges=False, max_x=0, max_y=0): """Return whether input region passes minimum area and average intensity checks""" check = True minr, minc, maxr, maxc = region.bbox if edges: edge_check = (minr != 0) * (minc != 0) edge_check *= (maxr != max_x) edge_check *= (maxc != max_y) check *= edge_check check *= region.filled_area >= min_size if region._intensity_image is not None: region_filter = (region.image * region.intensity_image) region_frac = region_filter.sum() / region.filled_area check *= (region_frac >= min_frac) return check
[docs]def region_swap(masks, images, min_sizes, min_fracs): """Performs a region_check on each region present in masks using images as intensity image. If check fails, removes region from mask and performs another region_check using same region with other image as intensity image. If this check passes, assigns region onto other mask.""" for i, j in [[0, 1], [1, 0]]: labels = measure.label(masks[i].astype(np.int)) for region_1 in measure.regionprops( labels, intensity_image=images[i]): if not region_check(region_1, min_sizes[i], min_fracs[i]): minr, minc, maxr, maxc = region_1.bbox indices = np.mgrid[minr:maxr, minc:maxc] masks[i][np.where(labels == region_1.label)] = False region_2 = measure.regionprops( np.array(region_1.image, dtype=int), intensity_image=images[j][(indices[0], indices[1])])[0] if region_check(region_2, 0, min_fracs[j]): masks[j][np.where(labels == region_1.label)] = True
[docs]def mean_binary(binaries, image, iterations=1, min_intensity=0, area_threshold=0, sigma=None): """Compares two binary of image and produces a filter based on the overlap""" intensity_map = image * np.mean(binaries, axis=0) intensity_mask = np.where(intensity_map > min_intensity, True, False) # Remove small holes and objects from masks intensity_mask = remove_small_holes( intensity_mask, area_threshold=area_threshold) intensity_mask = remove_small_objects( intensity_mask, min_size=area_threshold) # Dilate image binary = binary_dilation(intensity_mask, iterations=iterations) smooth_binary(binary, sigma) return binary.astype(int)