phenotypic.detect.WatershedDetector#

class phenotypic.detect.WatershedDetector(footprint: Literal['auto'] | numpy.ndarray | int | None = None, min_size: int = 50, compactness: float = 0.001, connectivity: int = 1, relabel: bool = True, ignore_zeros: bool = False)[source]

Bases: ThresholdDetector

Detect and separate touching colonies by watershed segmentation on a distance-transform surface.

Threshold the plate image to a binary mask, compute a Euclidean distance transform to locate colony centres, seed markers at local maxima, and propagate labelled regions via watershed on the Sobel gradient. This region-growing approach individually labels colonies that are in physical contact – a scenario where global thresholding merges them into a single object. For a full comparison see Detection Strategies Compared.

Parameters:
  • footprint (Literal['auto'] | np.ndarray | int | None) – Structuring element for peak detection. 'auto' infers size from grid spacing (GridImage only); an int creates a diamond of that radius; an ndarray supplies a custom footprint; None (default) lets scikit-image choose. Larger footprints merge nearby peaks into fewer seeds; smaller footprints yield finer segmentation. Typical range: 5–50 (diamond radius in pixels).

  • min_size (int) – Minimum object area in pixels (default 50). Objects smaller than this are removed as dust or debris. Typical range: 20–200 depending on image resolution and colony size.

  • compactness (float) – Watershed compactness parameter (default 0.001). Higher values enforce more regularly shaped segments; lower values let regions follow intensity gradients freely. Typical range: 0.0001–0.1. Increase if colonies are round and over-segmented; decrease for irregular morphologies.

  • connectivity (int) – Connectivity for region labelling (1 = 4-connected, 2 = 8-connected; default 1). Higher connectivity merges diagonally adjacent pixels.

  • relabel (bool) – If True (default), relabel segments to consecutive IDs after watershed.

  • ignore_zeros (bool) – If True (default), exclude zero-intensity pixels from threshold computation. Enable for plates with black borders or masked regions.

Returns:

Input image with objmap set to a labelled colony map where each colony receives a unique integer label. objmask is derived from the non-zero region of the label map.

Return type:

Image

Raises:

ValueError – If invalid parameters are provided or if the distance transform / watershed computation fails.

Best For:
  • Dense plates where colonies touch or overlap and must be counted individually.

  • Plates with variable colony sizes (e.g., mutant libraries) where the distance transform naturally adapts seed placement.

  • Irregular colony morphologies that follow local intensity gradients better than geometric assumptions.

  • Post-incubation plates where colony crowding is the primary segmentation challenge.

Consider Also:
  • OtsuDetector when colonies are well-separated and a simple binary mask suffices.

  • RoundPeaksDetector when colonies sit on a regular pinned grid and peak-based assignment is more efficient.

  • FilamentousFungiDetector when colonies exhibit spreading, filamentous growth rather than compact morphology.

  • CannyDetector when edge contrast is stronger than intensity contrast for delineating colony boundaries.

References

[1] S. Beucher and C. Lantuejoul, “Use of watersheds in contour detection,” in Proc. Int. Workshop on Image Processing, CCETT, Rennes, France, 1979.

See also

Tutorial 2: Detecting Colonies

Step-by-step tutorial for basic colony detection.

How To: Choose a Detection Algorithm

Guide for selecting the right detector for your plate images.

Detection Strategies Compared

In-depth comparison of all detection strategies.

Methods

__init__

apply

Detect colonies using sinusoidal cross-correlation grid estimation.

widget

Return (and optionally display) the root widget.

__del__()

Automatically stop tracemalloc when the object is deleted.

__getstate__()

Prepare the object for pickling by disposing of any widgets.

This ensures that UI components (which may contain unpickleable objects like input functions or thread locks) are cleaned up before serialization.

Note

This method modifies the object state by calling dispose_widgets(). Any active widgets will be detached from the object.

apply(image, inplace=False)

Detect colonies using sinusoidal cross-correlation grid estimation.

This method performs the core detection workflow: 1. Extract grid dimensions (if GridImage) 2. Threshold the detection matrix with adaptive kernel sizing 3. Remove noise if requested 4. Label connected components 5. Determine or estimate grid edges (via sinusoidal cross-correlation) 6. Assign dominant colonies to grid cells 7. Create final object map

Parameters:

image – Image object to process. Can be a regular Image or GridImage.

Returns:

The processed image with updated objmask and objmap.

Return type:

Image

widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.