phenotypic.measure.MeasureIntensity#

class phenotypic.measure.MeasureIntensity[source]#

Bases: MeasureFeatures

Measure grayscale intensity statistics of detected microbial colonies.

This class computes quantitative intensity metrics from the grayscale representation of each detected colony, including integrated intensity (total brightness), percentiles (min, Q1, median, Q3, max), and variability measures (standard deviation, coefficient of variation). These statistics reflect colony optical density, biomass, and internal heterogeneity on agar plates.

Intuition: Colony brightness in grayscale images correlates with biomass accumulation, cell density, and optical density. A low average intensity indicates sparse or translucent growth, while high intensity suggests dense mycelial mat or concentrated cells. Intensity variance within a colony reveals sectoring, differential growth rates, or uneven mycelial coverage. Integrated intensity (sum of all pixels) scales with both biomass and area, making it useful for growth kinetics tracking.

Use cases (agar plates): - Track colony growth over time via integrated intensity measurements (approximates optical density

without requiring liquid suspension).

  • Detect metabolically stressed or slow-growing colonies via low mean intensity.

  • Identify sectored, mutant, or chimeric colonies by high intensity variance within a single object.

  • Assess pigmentation or mycelial density differences between wild-type and mutant strains.

  • Enable automated colony picking strategies based on intensity thresholds (e.g., select only colonies above a biomass threshold).

Caveats: - Intensity depends critically on imaging conditions (lighting, exposure, camera gain); standardize

these settings across plates and experiments for reliable comparisons.

  • Grayscale conversion to luminance (Y channel) may not capture all visual information from colored agar or pigmented colonies; use enhanced grayscale (enh_gray) for better contrast, or measure color separately.

  • Integrated intensity mixes area and brightness; normalize by area or use intensity density (mean) for size-independent comparisons.

  • Shadows or uneven lighting on the plate cause local intensity artifacts; preprocessing with background subtraction or illumination correction may improve quality.

  • Outliers (very bright or very dark pixels from debris, bubble, or focus issues) can inflate standard deviation; use robust statistics (IQR) for noise-resistant variability assessment.

Returns:
pd.DataFrame: Object-level intensity statistics with columns:
  • Label: Unique object identifier.

  • IntegratedIntensity: Sum of all grayscale pixel values in the colony.

  • MinimumIntensity, MaximumIntensity: Range of intensity values.

  • MeanIntensity, MedianIntensity: Central tendency (mean more sensitive to outliers).

  • LowerQuartileIntensity, UpperQuartileIntensity: 25th and 75th percentiles (robust measures).

  • InterquartileRangeIntensity: Q3 - Q1 (robust measure of spread).

  • StandardDeviationIntensity: Sample standard deviation.

  • CoefficientVarianceIntensity: Normalized variability (std dev / mean, unitless).

Examples:
Measure colony biomass via intensity
from phenotypic import Image
from phenotypic.detect import OtsuDetector
from phenotypic.measure import MeasureIntensity

# Load and process plate image
image = Image.from_image_path("colony_plate_t24h.jpg")
detector = OtsuDetector()
image = detector.operate(image)

# Measure intensity to estimate biomass
measurer = MeasureIntensity()
intensity = measurer.operate(image)

# Track colonies by integrated intensity (proxy for biomass)
high_biomass = intensity[intensity['Intensity_IntegratedIntensity'] > 100000]
print(f"Colonies with high biomass (>100k): {len(high_biomass)}")
Identify heterogeneous or sectored colonies
# Measure intensity variance to detect sectoring
intensity = measurer.operate(image)

# Colonies with high variance may be sectored or chimeric
sectored = intensity[
    intensity['Intensity_CoefficientVarianceIntensity'] >
    intensity['Intensity_CoefficientVarianceIntensity'].quantile(0.75)
]
print(f"Potentially sectored colonies: {list(sectored.index)}")
Category: INTENSITY#

Name

Description

IntegratedIntensity

The sum of the object’s pixels

MinimumIntensity

The minimum intensity of the object

MaximumIntensity

The maximum intensity of the object

MeanIntensity

The mean intensity of the object

MedianIntensity

The median intensity of the object

StandardDeviationIntensity

The standard deviation of the object

CoefficientVarianceIntensity

The coefficient of variation of the object

LowerQuartileIntensity

The lower quartile intensity of the object

UpperQuartileIntensity

The upper quartile intensity of the object

InterquartileRangeIntensity

The interquartile range of the object

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', ...]