Source code for phenotypic.detect._minimum_detector

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from phenotypic._core._image import Image
from skimage.filters import threshold_minimum
from skimage.segmentation import clear_border

from ..abc_ import ThresholdDetector


[docs] class MinimumDetector(ThresholdDetector): """Detect colonies by thresholding at the intensity valley between two histogram peaks. Locate the minimum intensity value (valley) between the two dominant peaks of the image histogram and set it as the threshold. The resulting binary mask places the colony–background boundary at the natural gap in the intensity distribution. For a full comparison of detection strategies see :doc:`/explanation/detection_strategies_compared`. Best For: - High-contrast plates where colony and background intensities form two distinct, well-separated histogram peaks. - Standardised imaging setups producing consistently bimodal histograms across plates. - Images where the intensity gap between colonies and agar is wide and the valley is unambiguous. Consider Also: - :class:`OtsuDetector` when the histogram is bimodal but peaks are broad or partially overlapping. - :class:`LiDetector` when the histogram is unimodal or weakly bimodal and a cross-entropy criterion is more appropriate. - :class:`HysteresisDetector` when colony brightness varies across the plate and a single valley-based threshold under-segments faint regions. Args: ignore_zeros: Exclude zero-intensity pixels from the histogram before locating the valley. Enable for plates with black borders or masked regions. Default: False. ignore_borders: Remove colonies touching image edges via ``clear_border()``. Recommended for grid-based colony counting to eliminate partial colonies at plate boundaries. Default: True. Returns: Image: Input image with ``objmask`` set to the binary colony mask and ``objmap`` set to labeled connected components. Raises: ValueError: If the histogram has no clear bimodal distribution and no valley can be identified. See Also: :doc:`/tutorials/notebooks/02_detecting_colonies` for a step-by-step tutorial on basic colony detection. :doc:`/how_to/notebooks/choose_detection_algorithm` for guidance on selecting the right detector for your plate images. :doc:`/explanation/detection_strategies_compared` for an in-depth comparison of all thresholding strategies. """ ignore_zeros: bool = False ignore_borders: bool = True def _operate(self, image: Image) -> Image: """Binarizes the given image matrix using the Minimum threshold method. This function modifies the arr image by applying a binary mask to its enhanced matrix (`detect_mat`). The binarization threshold is automatically determined using Minimum method. The resulting binary mask is stored in the image's `objmask` attribute. Args: image (Image): The arr image object. It must have an `detect_mat` attribute, which is used as the basis for creating the binary mask. Returns: Image: The arr image object with its `objmask` attribute updated to the computed binary mask other_image. """ enh_matrix = image.detect_mat[:] nbins = 2**image.bit_depth mask = image.detect_mat[:] >= threshold_minimum( enh_matrix[enh_matrix != 0] if self.ignore_zeros else enh_matrix, nbins=nbins, ) mask = clear_border(mask) if self.ignore_borders else mask image.objmask = mask return image
# Set the docstring so that it appears in the sphinx documentation MinimumDetector.apply.__doc__ = MinimumDetector._operate.__doc__