phenotypic.measure.MeasureBounds#

class phenotypic.measure.MeasureBounds[source]#

Bases: MeasureFeatures

Extract spatial boundaries and centroids of detected microbial colonies.

This class computes the bounding box coordinates and centroid position of each detected colony in the image. These measurements form the foundation for shape analysis, grid alignment assessment, and spatial statistics in colony phenotyping workflows.

Intuition: Every detected colony occupies a region in the image; understanding its bounds and center is essential for downstream analyses. The bounding box defines the minimal rectangular region containing the colony, while centroids enable distance-based metrics (e.g., grid alignment, spread measurements) and are used to relate colonies to expected well positions in arrayed assays.

Use cases (agar plates): - Establish the spatial footprint of each detected colony for morphological analysis. - Compute centroids for aligning colonies to grid positions in high-throughput assays. - Enable region-of-interest (ROI) extraction for downstream intensity, color, or texture measurements. - Assess colony positioning relative to plate edges to detect spreading beyond well boundaries. - Support grid refinement operations by providing predicted centroid positions for outlier filtering.

Caveats: - Bounding box depends entirely on accurate object segmentation/masking; poor or over-segmented masks

yield misleading bounds.

  • Bounding box is axis-aligned; it may include empty space for rotated or crescent-shaped colonies.

  • Centroid assumes the colony is a connected component; fragmented or multi-component objects will have unreliable centroid positions.

  • Boundaries are computed in image pixel coordinates; they must be scaled or transformed if results are used with data in different coordinate systems (e.g., physical microns).

Returns:
pd.DataFrame: Object-level spatial data with columns:
  • Label: Unique object identifier.

  • CenterRR, CenterCC: Centroid row and column coordinates.

  • MinRR, MinCC: Minimum (top-left) row and column of bounding box.

  • MaxRR, MaxCC: Maximum (bottom-right) row and column of bounding box.

Examples:
Extract colony boundaries for a plate image
from phenotypic import Image
from phenotypic.detect import OtsuDetector
from phenotypic.measure import MeasureBounds

# Load image and detect colonies
image = Image.from_image_path("colony_plate.jpg")
detector = OtsuDetector()
image = detector.operate(image)

# Extract boundaries
boundsizer = MeasureBounds()
bounds = boundsizer.operate(image)
print(bounds.head())
# Output: Label, CenterRR, CenterCC, MinRR, MinCC, MaxRR, MaxCC
Use boundaries to extract colony ROIs
# Extract a region for each colony for detailed analysis
bounds = boundsizer.operate(image)
for idx, row in bounds.iterrows():
    min_rr, max_rr = int(row['BBOX_MinRR']), int(row['BBOX_MaxRR'])
    min_cc, max_cc = int(row['BBOX_MinCC']), int(row['BBOX_MaxCC'])
    colony_roi = image.rgb[min_rr:max_rr, min_cc:max_cc]
    # Process ROI independently (e.g., color analysis, morphology)
Category: BBOX#

Name

Description

CenterRR

The row coordinate of the center of the bounding box.

MinRR

The smallest row coordinate of the bounding box.

MaxRR

The largest row coordinate of the bounding box.

CenterCC

The column coordinate of the center of the bounding box.

MinCC

The smallest column coordinate of the bounding box.

MaxCC

The largest column coordinate of the bounding box.

Methods

__init__

measure

Execute the measurement operation on a detected-object image.

__del__()#

Automatically stop tracemalloc when the object is deleted.

measure(image, include_meta=False)#

Execute the measurement operation on a detected-object image.

This is the main public API method for extracting measurements. It handles: input validation, parameter extraction via introspection, calling the subclass-specific _operate() method, optional metadata merging, and exception handling.

How it works (for users):

  1. Pass your processed Image (with detected objects) to measure()

  2. The method calls your subclass’s _operate() implementation

  3. Results are validated and returned as a pandas DataFrame

  4. If include_meta=True, image metadata (filename, grid info) is merged in

How it works (for developers):

When you subclass MeasureFeatures, you only implement _operate(). This measure() method automatically:

  • Extracts __init__ parameters from your instance (introspection)

  • Passes matched parameters to _operate() as keyword arguments

  • Validates the Image has detected objects (objmap)

  • Wraps exceptions in OperationFailedError with context

  • Merges grid/object metadata if requested

Parameters:
  • image (Image) – A PhenoTypic Image object with detected objects (must have non-empty objmap from a prior detection operation).

  • include_meta (bool, optional) – If True, merge image metadata columns (filename, grid position, etc.) into the results DataFrame. Defaults to False.

Returns:

Measurement results with structure:

  • First column: OBJECT.LABEL (integer IDs from image.objmap[:])

  • Remaining columns: Measurement values (float, int, or string)

  • One row per detected object

If include_meta=True, additional metadata columns are prepended before OBJECT.LABEL (e.g., Filename, GridRow, GridCol).

Return type:

pd.DataFrame

Raises:

OperationFailedError – If _operate() raises any exception, it is caught and re-raised as OperationFailedError with details including the original exception type, message, image name, and operation class. This provides consistent error handling across all measurers.

Notes

  • This method is the main entry point; do not override in subclasses

  • Subclasses implement _operate() only, not this method

  • Automatic memory profiling is available via logging configuration

  • Image must have detected objects (image.objmap should be non-empty)

Examples

Basic measurement extraction
from phenotypic import Image
from phenotypic.measure import MeasureSize
from phenotypic.detect import OtsuDetector

# Load and detect
image = Image.from_image_path('plate.jpg')
image = OtsuDetector().operate(image)

# Extract measurements
measurer = MeasureSize()
df = measurer.measure(image)
print(df.head())
Include metadata in measurements
# With image metadata (filename, grid info)
df_with_meta = measurer.measure(image, include_meta=True)
print(df_with_meta.columns)
# Output: ['Filename', 'GridRow', 'GridCol', 'OBJECT.LABEL',
#          'Area', 'IntegratedIntensity', ...]