Source code for pyfibre.addons.shg_pl_trans.tools.segmentation

import numpy as np
from scipy.ndimage import binary_dilation, binary_closing
from skimage.exposure import equalize_adapthist, rescale_intensity
from skimage.filters import threshold_mean
from skimage.morphology import remove_small_holes

from pyfibre.model.objects.segments import FibreSegment, CellSegment
from pyfibre.model.tools.convertors import binary_to_segments
from pyfibre.model.tools.segmentation import (
    create_fibre_filter, rgb_segmentation)
from pyfibre.model.tools.utilities import mean_binary, region_swap

from .shg_pl_trans_kmeans_filter import SHGPLTransKmeansFilter


[docs]def fibre_cell_region_swap(multi_image, fibre_mask, cell_mask): """Obtain segments from masks and swap over any incorrectly assigned segments""" region_swap( [cell_mask, fibre_mask], [multi_image.pl_image, multi_image.shg_image], [250, 150], [0.01, 0.1]) fibre_mask = remove_small_holes(fibre_mask) cell_mask = remove_small_holes(cell_mask) return fibre_mask, cell_mask
[docs]def shg_segmentation( multi_image, fibre_networks, min_fibre_size=100, min_cell_size=200, min_fibre_frac=100, min_cell_frac=0.001, **kwargs): fibre_filter = create_fibre_filter( fibre_networks, multi_image.shape) fibre_binary = np.where(fibre_filter > 0.1, 0, 1) cell_binary = np.where(fibre_binary, 0, 1) # Create a new set of segments for each fibre region fibre_segments = binary_to_segments( fibre_binary, FibreSegment, intensity_image=multi_image.shg_image, min_size=min_fibre_size, min_frac=min_fibre_frac) # Create a new set of segments for each cell region cell_segments = binary_to_segments( cell_binary, CellSegment, intensity_image=multi_image.shg_image, min_size=min_cell_size, min_frac=min_cell_frac) return fibre_segments, cell_segments
[docs]def shg_pl_trans_segmentation( multi_image, fibre_networks, min_fibre_size=100, min_cell_size=200, min_fibre_frac=100, min_cell_frac=0.1, scale=1.0, **kwargs): norm_stack = [ rescale_intensity(image) for image in multi_image.preprocess_images() ] # Create an image stack for the rgb_segmentation from SHG and PL # images fibre_filter = create_fibre_filter( fibre_networks, multi_image.shape) original_binary = np.where( fibre_filter >= threshold_mean(fibre_filter), 1, 0 ) # Create composite RGB image from SHG, PL and transmission stack = (norm_stack[0], np.sqrt(norm_stack[1] * norm_stack[2]), equalize_adapthist(norm_stack[2])) # Segment the PL image using k-means clustering fibre_mask, cell_mask = rgb_segmentation( stack, SHGPLTransKmeansFilter(), scale=scale) # Swap over any pixel areas that may have been wrongly assigned fibre_mask, cell_mask = fibre_cell_region_swap( multi_image, fibre_mask, cell_mask) # Create a binary for the fibrous regions based on information # obtained from the rgb segmentation fibre_mask = binary_dilation(fibre_mask, iterations=2) fibre_mask = binary_closing(fibre_mask) new_binary = fibre_mask.astype(int) # Generate a filter for the SHG image that combines information # from both FIRE and k-means algorithms fibre_binary = mean_binary( np.array([original_binary, new_binary]), norm_stack[0], min_intensity=0.10) cell_binary = np.where(fibre_binary, 0, 1) # Create a new set of segments for each fibre region fibre_segments = binary_to_segments( fibre_binary, FibreSegment, intensity_image=multi_image.shg_image, min_size=min_fibre_size, min_frac=min_fibre_frac) # Create a new set of segments for each cell region cell_segments = binary_to_segments( cell_binary, CellSegment, intensity_image=multi_image.pl_image, min_size=min_cell_size, min_frac=min_cell_frac) return fibre_segments, cell_segments