Source code for phenotypic.enhance._subtract_gaussian

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from phenotypic._core._image import Image

import numpy as np
from skimage.filters import gaussian

from phenotypic.abc_ import ImageEnhancer


[docs] class SubtractGaussian(ImageEnhancer): """Remove background from ``detect_mat`` by subtracting a Gaussian-blurred estimate. Estimates a smooth background via Gaussian blur and subtracts it, removing gradual illumination gradients (vignetting, agar thickness, scanner shading) while retaining sharp colony features. Improves downstream thresholding and edge detection. For algorithm details, see :doc:`/explanation/what_enhancement_does`. Args: sigma: Gaussian standard deviation defining the background scale. Must be larger than the typical colony diameter. Typical range: 20--100. Default: 50.0. mode: Border handling. Accepted values: ``'reflect'`` (default), ``'constant'``, ``'nearest'``, ``'mirror'``, ``'wrap'``. cval: Fill value when ``mode='constant'``. Default: 0.0. truncate: Gaussian support in standard deviations. Default: 4.0. preserve_range: Preserve the input value range during filtering. Default: ``True``. n_iter: Number of successive subtraction passes. Multiple passes remove residual background from complex gradients. Typical range: 1--3. Default: 1. Returns: Image: Input image with ``detect_mat`` background-subtracted and clipped to [0, 1]. ``rgb`` and ``gray`` are unchanged. Best For: - Correcting uneven lighting across plates or scan beds. - Flattening background to enhance dark colonies on bright agar. - Normalizing batches captured with varying exposure or illumination profiles. Consider Also: - :class:`SubtractRollingBall` for parabolic background estimation that adapts to non-Gaussian intensity ramps. - :class:`OpeningSubtractBg` for faster morphological background subtraction in high-throughput pipelines. - :class:`BilateralDenoise` when the primary issue is noise rather than illumination gradients. See Also: :doc:`/tutorials/notebooks/03_enhancing_before_detection` for a visual walkthrough of background subtraction on plate images. :doc:`/explanation/what_enhancement_does` for background on illumination correction strategies. """
[docs] def __init__( self, sigma: float = 50.0, mode: str = "reflect", cval: float = 0.0, truncate: float = 4.0, preserve_range: bool = True, n_iter: int = 1, ): """ Parameters: sigma (float): Background scale. Set larger than colony diameter so colonies are preserved while slow illumination is removed. mode (str): Border handling; 'reflect' reduces artificial rims on plates. cval (float): Fill value when `mode='constant'`. truncate (float): Gaussian support in standard deviations (advanced). preserve_range (bool): Keep the original intensity range; useful if subsequent steps or measurements assume a specific scaling. n_iter (int): Number of successive subtraction passes. Must be >= 1. One pass (default) removes a single background estimate. Multiple passes (2+) iteratively subtract residual background, useful for complex or multi-scale illumination gradients. """ if n_iter < 1: raise ValueError("n_iter must be >= 1") self.sigma: float = sigma self.mode: str = mode self.cval: float = cval self.truncate: float = truncate self.preserve_range: bool = preserve_range self.n_iter: int = n_iter
def _operate(self, image: Image) -> Image: for _ in range(self.n_iter): background = gaussian( image=image.detect_mat[:], sigma=self.sigma, mode=self.mode, cval=self.cval, truncate=self.truncate, preserve_range=self.preserve_range, ) image.detect_mat[:] = np.clip((image.detect_mat[:].copy() - background), a_min=0.0, a_max=1.0) return image