Source code for pywsi.segmentation.binary_segmentation

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from scipy.stats import poisson
from skimage.color import rgb2gray
from sklearn import mixture
import numpy as np


[docs]def poisson_deconvolve(h_channel_image): """Separate baclground and foreground intensities by doing a poisson partition. For the i_th pixel h(i) = P0*P(i|0) + P1*P(i|1) where P0,P1 are prior probabilities of background and foreground. For a threshold t, the parameters are given by: P(t) = \sum_{i=0}^t h(i) \mu_0(t) = 1/P0(t) * \sum_{i=0}^t i*h(i) P1(t) = \sum_{i=t+1}^I_max h(i) \mu_1(t) = 1/P1(t) * \sum_{i=t+1}^I_max i*h(i) Parameters ---------- h_channel_image: array_like uint8 image (single channel) """ assert np.issubdtype(h_channel_image.dtype, np.integer), 'Input should be int dtype' eps = np.finfo('float').eps h, bin_edges = np.histogram( np.ravel(h_channel_image), bins=256, range=(0, 256)) h_normalized = h.astype('float') / h.sum() cumul_sum = np.cumsum(h_normalized) product = np.multiply(bin_edges[:-1], h_normalized) cumul_product = np.cumsum(product) p0 = cumul_sum p0[p0 <= 0] = eps p1 = 1 - cumul_sum p1[p1 <= 0] = eps mu = np.mean(np.ravel(h_channel_image)) mu0 = np.divide(cumul_product, p0) + eps mu1 = np.divide(cumul_product[-1] - cumul_product, p1) + eps cost = mu - np.multiply(p0, np.log(p0) + np.multiply(mu0, np.log(mu0))) \ - np.multiply(p1, np.log(p1) + np.multiply(mu1, np.log(mu1))) min_cost_index = np.argmin(cost) mu0_opt = mu0[min_cost_index] mu1_opt = mu1[min_cost_index] t_opt = bin_edges[min_cost_index] foreground = poisson.pmf(np.arange(0, 256), mu1_opt)[h_channel_image] background = poisson.pmf(np.arange(0, 256), mu0_opt)[h_channel_image] opts = {'t': t_opt, 'mu0_opt': mu0_opt, 'mu1_opt': mu1_opt} return foreground.reshape(h_channel_image.shape), background.reshape( h_channel_image.shape), opts
[docs]def gmm_thresholding(image_rgb): """Perform thresholding based on Gaussian mixture models. The image is assumed to be a mixture of two gaussians. A lower mean sample belongs to the blobs while the higher mean shows the white background. Parameters ---------- image_rgb: array_like RGB input Returns ------ gmm_threshold: float GMM mean (minimum) of the two mixing populations clf: sklearn.GaussianMixture The entire sklearn model """ clf = mixture.GaussianMixture(n_components=2, covariance_type='full') clf.fit(rgb2gray(image_rgb).flatten().reshape(-1, 1)) return clf.means_.min(), clf