Source code for pywsi.segmentation.diff_gaussian

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

from scipy.ndimage.morphology import distance_transform_edt
from scipy.ndimage.filters import gaussian_filter
from skimage.transform import resize
import numpy as np


[docs]def downsample(image, factor=2): return image[::factor, ::factor]
[docs]def laplace_of_gaussian(input_image, foreground_mask, sigma_min, sigma_max, n_octave_levels=3): eps = np.finfo('float').eps input_image = input_image.astype('float') image_dist_transform = distance_transform_edt(foreground_mask) sigma_upper_bound = 2 * image_dist_transform sigma_upper_bound = np.clip(sigma_upper_bound, sigma_min, sigma_max) delta_sigma = 2**(1.0 / n_octave_levels) sigma_ratio = sigma_max / sigma_min n_levels = np.ceil(np.log(sigma_ratio) / np.log(delta_sigma)).astype(int) sigma_prev = sigma_min convolution_prev = gaussian_filter(input_image, sigma_prev) sigma_upper_bound_cur = sigma_upper_bound.copy() dog_max = np.zeros_like(input_image) dog_max[:, :] = eps dog_octave_max = dog_max.copy() sigma_max = np.zeros_like(input_image) sigma_octave_max = np.zeros_like(input_image) n_level = 0 n_octave = 0 for level_cur in range(n_levels + 1): sigma_cur = sigma_prev * delta_sigma sigma_conv = np.sqrt(sigma_cur**2 - sigma_prev**2) sigma_conv /= 2**n_octave convolution_cur = gaussian_filter(convolution_prev, sigma_conv) dog_cur = convolution_cur - convolution_prev dog_cur[sigma_upper_bound_cur < sigma_prev] = eps pixels_to_update = np.where(dog_cur > dog_octave_max) if len(pixels_to_update[0]) > 0: dog_octave_max[pixels_to_update] = dog_cur[pixels_to_update] sigma_octave_max[pixels_to_update] = sigma_prev sigma_prev = sigma_cur convolution_prev = convolution_cur n_level += 1 # Do additional processing at the end of each octave if level_cur == n_levels or n_level == n_octave_levels: # update maxima if n_octave_levels > 0: dog_octave_max_resized = resize( dog_octave_max, dog_max.shape, order=0, mode='constant') else: dog_octave_max_resized = dog_octave_max max_pixels = np.where(dog_octave_max_resized > dog_max) if len(max_pixels[0]) > 0: dog_max[max_pixels] = \ dog_octave_max_resized[max_pixels] if n_octave_levels > 0: sigma_octave_max_resized = resize( sigma_octave_max, dog_max.shape, order=0, mode='constant') else: sigma_octave_max_resized = sigma_octave_max sigma_max[max_pixels] = \ sigma_octave_max_resized[max_pixels] if n_level == n_octave_levels: convolution_prev = downsample(convolution_cur) sigma_upper_bound_cur = downsample(sigma_upper_bound_cur) dog_octave_max = downsample(dog_octave_max) sigma_octave_max = downsample(sigma_octave_max) n_level = 0 n_octave += 1 dog_max[dog_max == eps] = 0 return dog_max, sigma_max