phenotypic.detect.CannyDetector#

class phenotypic.detect.CannyDetector(sigma: float = 1.0, low_threshold: float = 0.1, high_threshold: float = 0.2, use_quantiles: bool = True, min_size: int = 50, invert_edges: bool = True, connectivity: int = 2)[source]

Bases: ThresholdDetector

Detect colonies by Canny edge detection and enclosed-region labelling.

Apply multi-stage Canny edge detection (Gaussian smoothing, gradient magnitude, non-maximum suppression, hysteresis thresholding) to produce thin, connected boundary contours, then label the enclosed regions as individual colonies. This edge-based approach segments colonies by boundary contrast rather than absolute intensity, making it effective on plates with uneven illumination or translucent colonies. For a full comparison see Detection Strategies Compared.

Parameters:
  • sigma (float) – Gaussian smoothing standard deviation before edge detection (default 1.0). Higher values suppress noise and spurious edges but may blur fine boundaries or merge nearby colonies. Typical range: 0.5–3.0. Start with 1.0 for clean images; increase to 2.0–3.0 for noisy scans.

  • low_threshold (float) – Lower hysteresis threshold (default 0.1). When use_quantiles is True, this is a fraction (0.1 = retain edges stronger than 10 % of gradient magnitudes). When False, an absolute gradient value. Increase to suppress weak noise edges. Typical quantile range: 0.05–0.2.

  • high_threshold (float) – Upper hysteresis threshold seeding edge traces (default 0.2). Same interpretation as low_threshold. Must exceed low_threshold. Typical quantile range: 0.1–0.4.

  • use_quantiles (bool) – If True (default), interpret thresholds as gradient- magnitude quantiles, adapting automatically to image contrast. Set to False for absolute gradient values when imaging conditions are tightly controlled.

  • min_size (int) – Minimum object area in pixels (default 50). Increase to filter dust, debris, and plate-edge artefacts; decrease to retain tiny colonies. Typical range: 20–500.

  • invert_edges (bool) – If True (default), label enclosed regions as colony objects. If False, label edge pixels themselves (useful for debugging edge quality).

  • connectivity (int) – Connectivity for region labelling (1 = 4-connected, 2 = 8-connected; default 2). Higher connectivity bridges diagonal gaps in edge contours.

Returns:

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

Return type:

Image

Raises:

ValueError – If high_threshold is less than low_threshold or if threshold values are outside the valid range.

Best For:
  • Well-separated colonies on solid media where colony edges are sharper than intensity differences relative to background.

  • Translucent or lightly pigmented colonies that lack sufficient intensity contrast for threshold-based methods.

  • Plates with heterogeneous colony texture or pigmentation that fragments under watershed or simple thresholding.

  • Images with moderate vignetting where edge contrast is preserved even though absolute intensity varies spatially.

Consider Also:
  • OtsuDetector when colonies differ from background primarily in brightness rather than edge contrast.

  • WatershedDetector when touching colonies must be split by region-growing from interior seeds.

  • HysteresisDetector when dual-threshold intensity segmentation is preferred over edge-based detection.

References

[1] J. Canny, “A computational approach to edge detection,” IEEE Trans. Pattern Anal. Mach. Intell., vol. 8, no. 6, pp. 679–698, 1986.

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.

__init__(sigma: float = 1.0, low_threshold: float = 0.1, high_threshold: float = 0.2, use_quantiles: bool = True, min_size: int = 50, invert_edges: bool = True, connectivity: int = 2)[source]
Parameters:
  • sigma (float) – Gaussian smoothing strength before edge detection. Start with 1-2 for clean images; increase for noisy scans to suppress spurious edges. Keep below typical colony width to avoid merging.

  • low_threshold (float) – Lower hysteresis threshold. If use_quantiles=True, a fraction (e.g., 0.1 = retain edges stronger than 10% of gradients). If False, an absolute gradient magnitude. Increase to suppress weak edges from noise; decrease to recover faint colony boundaries.

  • high_threshold (float) – Upper hysteresis threshold. Seeds edge traces. If use_quantiles=True, a fraction (e.g., 0.2 = top 80% gradients); if False, an absolute magnitude. Raise to focus on strong boundaries; lower to include fainter edges. Must exceed low_threshold.

  • use_quantiles (bool) – Interpret thresholds as quantiles (True, default) or absolute values (False). Quantiles adapt to image contrast automatically, reducing manual tuning.

  • min_size (int) – Minimum object area in pixels. Increase to filter out dust, debris, and small artifacts; decrease to retain tiny colonies.

  • invert_edges (bool) – If True (default), label enclosed regions as objects (colonies). If False, label edge pixels (for atypical cases like ring colonies or edge quality checks).

  • connectivity (int) – Connectivity for labeling regions (1 or 2 in 2D). Higher values merge diagonally touching pixels, useful for bridging fragmented boundaries but may merge touching colonies.

__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.