Source code for spinningdiskanalyzer.imaging.filters

"""In-memory filtering of images"""

from skimage import restoration
from pythreshold.local_th.bernsen import bernsen_threshold
from numpy import ndarray
from numpy import where
from numpy import median
from logging import getLogger


log = getLogger(__name__)


[docs] def rolling_ball(image: ndarray, radius: int = 50) -> ndarray: """ Removes the background from the `image` using the rolling-ball method. Returns the image foreground obtained by subtracting the background from the input image. """ log.info('Started background correction using rolling-ball method.') background = restoration.rolling_ball(image, radius=radius) foreground = where(image > background, image - background, 0) log.info('Finished background correction using rolling-ball method.') return foreground
[docs] def thresholding_bernsen( image: ndarray, radius: int = 15, contrast: int = 15, ) -> ndarray: """ Returns the local segmentation thresholds using the Bernsen method. The parameters window `radius` and `contrast` threshold correspond to the [ImageJ definitions], though the [Python implementation] actually uses a square window with a side length corresponding to the diameter. [ImageJ definitions]: https://imagej.net/plugins/auto-local-threshold [Python implementation]: https://github.com/manuelaguadomtz/pythreshold """ log.info('Started local thresholding using Bernsen method.') window = 2*radius + 1 thresholds = bernsen_threshold(image, w_size=window, c_thr=contrast) thresholded = where(image >= thresholds, 0, 255).astype('uint8') log.info('Finished local thresholding using Bernsen method.') return thresholded
[docs] def invert(image: ndarray) -> ndarray: """Returns the given `image` with all color values inverted.""" if image.dtype == 'uint16': max_int = 2**16 - 1 elif image.dtype == 'uint8': max_int = 2**8 - 1 else: raise ValueError('Image data must be either 8- or 16-bit integer.') return (max_int - image)
[docs] def white_on_black(image: ndarray) -> ndarray: """ Inverts the `image` if not white-on-black, or returns the input. By "white-on-black" we mean that the background is mostly dark with light features on it. """ if median(image) > image.max()/2: return invert(image) else: return image
[docs] def black_on_white(image: ndarray) -> ndarray: """ Inverts the `image` if not black-on-white, or returns the input. By "black-on-white" we mean that the background is mostly light with dark features on it. """ if median(image) <= image.max()/2: return invert(image) else: return image