phenotypic.measure#
Feature extraction from detected fungal colonies.
Computes per-colony and grid-level metrics describing growth, morphology, and appearance on agar plates. Measurements span bounds, size/integrated intensity, shape descriptors, texture, color, and grid-level statistics such as spatial spread and linear gradients. Results are returned as pandas DataFrames ready for analysis.
Classes
Extract bounding box coordinates and centroids of detected colonies. |
|
Measure colony color statistics across multiple perceptual color spaces. |
|
Measure grayscale intensity statistics of detected colonies. |
|
Measure comprehensive morphological characteristics of detected colonies. |
|
Measure colony area and integrated intensity as lightweight size proxies. |
|
Measure colony radial expansion and angular symmetry from the object mask alone. |
|
Measure colony surface texture using Haralick features from gray-level co-occurrence matrices. |
|
Quantify within-well colony dispersion using pairwise centroid distances. |
|
Evaluate grid alignment quality using row-wise and column-wise linear regression. |
|
Measure edge-to-edge distances to neighbors in adjacent grid cells. |
- class phenotypic.measure.MeasureBounds(*args, **kwargs)[source]
Bases:
MeasureFeaturesExtract bounding box coordinates and centroids of detected colonies.
Compute the axis-aligned bounding box and centroid (geometric and intensity-weighted) for each detected colony. These spatial measurements form the foundation for region-of-interest extraction, grid alignment assessment, and neighbor-distance calculations.
- Returns:
pd.DataFrame: Object-level spatial data with columns:
Label: unique object identifier.
CenterRR, CenterCC: geometric centroid coordinates.
IntensityWeightedCenterRR, IntensityWeightedCenterCC: intensity-weighted centroid coordinates (skimage
centroid_weighted).DistWeightedCenterRR, DistWeightedCenterCC: row/column of the per-object distance-transform maximum (deepest interior point — robust to thin filamentous extensions).
MinRR, MinCC: top-left corner of bounding box.
MaxRR, MaxCC: bottom-right corner of bounding box.
- Best For:
Computing centroids for aligning colonies to expected grid positions in arrayed assays.
Extracting region-of-interest crops for downstream intensity, color, or texture analysis.
Assessing colony positioning relative to plate edges or well boundaries.
- Consider Also:
MeasureShapefor full morphological metrics built on top of bounding box data.MeasureGridLinRegStatsfor regression-based grid alignment quality using centroid positions.MeasureGridSpatialfor neighbor distance calculations using bounding boxes.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data.
Category: BBOX# Name
Description
CenterRRThe row coordinate of the center of the bounding box.
MinRRThe smallest row coordinate of the bounding box.
MaxRRThe largest row coordinate of the bounding box.
CenterCCThe column coordinate of the center of the bounding box.
MinCCThe smallest column coordinate of the bounding box.
MaxCCThe largest column coordinate of the bounding box.
IntensityWeightedCenterRRThe intensity-weighted center row coordinate of the object (skimage
centroid_weighted).IntensityWeightedCenterCCThe intensity-weighted center column coordinate of the object (skimage
centroid_weighted).DistWeightedCenterRRRow coordinate of the per-object Euclidean-distance-transform maximum (deepest interior point of the object mask). Robust to thin filamentous extensions that pull intensity-weighted centroids off-body.
DistWeightedCenterCCColumn coordinate of the per-object Euclidean-distance-transform maximum (deepest interior point of the object mask). Robust to thin filamentous extensions that pull intensity-weighted centroids off-body.
- __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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureColor(white_chroma_max: float = 4.0, chroma_min: float = 8.0, include_XYZ: bool = False)[source]
Bases:
MeasureFeaturesMeasure colony color statistics across multiple perceptual color spaces.
Extract per-colony color features from CIE XYZ, chromaticity (xy), CIE Lab (perceptually uniform), and HSV color spaces. For each channel the standard statistical suite is computed (min, Q1, mean, median, Q3, max, std dev, coefficient of variation), plus Lab chroma estimates.
- Args:
- white_chroma_max: Lab chroma threshold below which a colony is
classified as achromatic (white). Default:
4.0.- chroma_min: Minimum chroma value retained in analysis; colonies
below this are treated as colorless. Default:
8.0.- include_XYZ: Compute CIE XYZ tristimulus statistics (slower).
Default:
False.
- Returns:
pd.DataFrame: Object-level color statistics with column groups:
ColorXYZ (X, Y, Z) – only when
include_XYZ=True.Colorxy (x, y chromaticity).
ColorLab (L*, a*, b*, ChromaEstimated).
ColorHSV (Hue, Saturation, Brightness).
Each channel has Min, Q1, Mean, Median, Q3, Max, StdDev, CoeffVar sub-columns.
- Best For:
Distinguishing pigmented colonies (carotenoid, melanin) from colorless ones to stratify phenotypes by pigmentation profile.
Detecting sectoring and growth heterogeneity via high within-colony color variance.
Cross-plate comparison of colony pigmentation using perceptually uniform Lab distances.
- Consider Also:
MeasureIntensityfor grayscale-only brightness and variability statistics.MeasureColorCompositionfor proportion-based color classification of colony pixels.MeasureTexturefor surface-roughness features that complement color metrics.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data. Measurement Metrics and Their Biological Meaning for interpreting color metrics in a biological context.
Category: ColorXYZ# Name
Description
CieXMinThe minimum X value of the object in CIE XYZ color space
CieXQ1The lower quartile (Q1) X value of the object in CIE XYZ color space
CieXMeanThe mean X value of the object in CIE XYZ color space
CieXMedianThe median X value of the object in CIE XYZ color space
CieXQ3The upper quartile (Q3) X value of the object in CIE XYZ color space
CieXMaxThe maximum X value of the object in CIE XYZ color space
CieXStdDevThe standard deviation of the X value of the object in CIE XYZ color space
CieXCoeffVarThe coefficient of variation of the X value of the object in CIE XYZ color space
CieYMinThe minimum Y value of the object in CIE XYZ color space
CieYQ1The lower quartile (Q1) Y value of the object in CIE XYZ color space
CieYMeanThe mean Y value of the object in CIE XYZ color space
CieYMedianThe median Y value of the object in CIE XYZ color space
CieYQ3The upper quartile (Q3) Y value of the object in CIE XYZ color space
CieYMaxThe maximum Y value of the object in CIE XYZ color space
CieYStdDevThe standard deviation of the Y value of the object in CIE XYZ color space
CieYCoeffVarThe coefficient of variation of the Y value of the object in CIE XYZ color space
CieZMinThe minimum Z value of the object in CIE XYZ color space
CieZQ1The lower quartile (Q1) Z value of the object in CIE XYZ color space
CieZMeanThe mean Z value of the object in CIE XYZ color space
CieZMedianThe median Z value of the object in CIE XYZ color space
CieZQ3The upper quartile (Q3) Z value of the object in CIE XYZ color space
CieZMaxThe maximum Z value of the object in CIE XYZ color space
CieZStdDevThe standard deviation of the Z value of the object in CIE XYZ color space
CieZCoeffVarThe coefficient of variation of the Z value of the object in CIE XYZ color space
Category: Colorxy# Name
Description
xMinThe minimum chromaticity x coordinate of the object
xQ1The lower quartile (Q1) chromaticity x coordinate of the object
xMeanThe mean chromaticity x coordinate of the object
xMedianThe median chromaticity x coordinate of the object
xQ3The upper quartile (Q3) chromaticity x coordinate of the object
xMaxThe maximum chromaticity x coordinate of the object
xStdDevThe standard deviation of the chromaticity x coordinate of the object
xCoeffVarThe coefficient of variation of the chromaticity x coordinate of the object
yMinThe minimum chromaticity y coordinate of the object
yQ1The lower quartile (Q1) chromaticity y coordinate of the object
yMeanThe mean chromaticity y coordinate of the object
yMedianThe median chromaticity y coordinate of the object
yQ3The upper quartile (Q3) chromaticity y coordinate of the object
yMaxThe maximum chromaticity y coordinate of the object
yStdDevThe standard deviation of the chromaticity y coordinate of the object
yCoeffVarThe coefficient of variation of the chromaticity y coordinate of the object
Category: ColorLab# Name
Description
L*MinThe minimum L* value of the object
L*Q1The lower quartile (Q1) L* value of the object
L*MeanThe mean L* value of the object
L*MedianThe median L* value of the object
L*Q3The upper quartile (Q3) L* value of the object
L*MaxThe maximum L* value of the object
L*StdDevThe standard deviation of the L* value of the object
L*CoeffVarThe coefficient of variation of the L* value of the object
a*MinThe minimum a* value of the object
a*Q1The lower quartile (Q1) a* value of the object
a*MeanThe mean a* value of the object
a*MedianThe median a* value of the object
a*Q3The upper quartile (Q3) a* value of the object
a*MaxThe maximum a* value of the object
a*StdDevThe standard deviation of the a* value of the object
a*CoeffVarThe coefficient of variation of the a* value of the object
b*MinThe minimum b* value of the object
b*Q1The lower quartile (Q1) b* value of the object
b*MeanThe mean b* value of the object
b*MedianThe median b* value of the object
b*Q3The upper quartile (Q3) b* value of the object
b*MaxThe maximum b* value of the object
b*StdDevThe standard deviation of the b* value of the object
b*CoeffVarThe coefficient of variation of the b* value of the object
ChromaEstimatedMeanThe mean chroma estimation of the object calculated using \(\(sqrt(a^{*}_{mean}^2 + b^{*}_{mean})^2}\)
ChromaEstimatedMedianThe median chroma estimation of the object using \(\sqrt({a*_{median}^2 + b*_{median})^2}\)
Category: ColorHSV# Name
Description
HueMinThe minimum hue of the object
HueQ1The lower quartile (Q1) hue of the object
HueMeanThe mean hue of the object
HueMedianThe median hue of the object
HueQ3The upper quartile (Q3) hue of the object
HueMaxThe maximum hue of the object
HueStdDevThe standard deviation of the hue of the object
HueCoeffVarThe coefficient of variation of the hue of the object
SaturationMinThe minimum saturation of the object
SaturationQ1The lower quartile (Q1) saturation of the object
SaturationMeanThe mean saturation of the object
SaturationMedianThe median saturation of the object
SaturationQ3The upper quartile (Q3) saturation of the object
SaturationMaxThe maximum saturation of the object
SaturationStdDevThe standard deviation of the saturation of the object
SaturationCoeffVarThe coefficient of variation of the saturation of the object
BrightnessMinThe minimum brightness of the object
BrightnessQ1The lower quartile (Q1) brightness of the object
BrightnessMeanThe mean brightness of the object
BrightnessMedianThe median brightness of the object
BrightnessQ3The upper quartile (Q3) brightness of the object
BrightnessMaxThe maximum brightness of the object
BrightnessStdDevThe standard deviation of the brightness of the object
BrightnessCoeffVarThe coefficient of variation of the brightness of the object
- __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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureGridLinRegStats(section_num: int | None = None)[source]
Bases:
GridMeasureFeaturesEvaluate grid alignment quality using row-wise and column-wise linear regression.
Fit linear regressions to colony centroid positions along each row and column of the grid, then compute per-colony residual error (Euclidean distance between observed and predicted centroid). High residual errors flag off-grid growth, misdetections, or plate warping.
- Args:
- section_num: Grid section index to restrict measurements to.
Nonemeasures across the entire grid. Default:None.
- Returns:
pd.DataFrame: Per-object metrics indexed by object label:
RowM, RowB: row regression slope and intercept.
ColM, ColB: column regression slope and intercept.
PredRR, PredCC: predicted centroid from regression.
ResidualError: Euclidean distance between actual and predicted centroid.
- Best For:
Identifying colonies that grew outside their designated grid position on arrayed plates.
Detecting systematic rotation or shear across the plate to validate grid detection quality.
Filtering or weighting colonies by positional confidence before downstream phenotypic analysis.
- Consider Also:
MeasureGridSpatialfor neighbor-distance metrics between adjacent grid cells.MeasureGridSpreadfor detecting over-segmentation and multi-object wells.MeasureBoundsfor raw centroid and bounding box coordinates without regression.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of grid-level measurements.
Category: GRID_LINREG_STATS# Name
Description
RowMSlope of row-wise linear regression fit across column positions. Measures systematic drift in row alignment. Values near 0 indicate horizontal rows; non-zero values suggest rotational misalignment or systematic row curvature across the plate.
RowBIntercept of row-wise linear regression fit. Represents the expected row coordinate when column position is 0. Combined with slope, defines the expected row trend line for quality assessment and position prediction.
ColMSlope of column-wise linear regression fit across row positions. Measures systematic drift in column alignment. Values near 0 indicate vertical columns; non-zero values suggest rotational misalignment or systematic column curvature across the plate.
ColBIntercept of column-wise linear regression fit. Represents the expected column coordinate when row position is 0. Combined with slope, defines the expected column trend line for quality assessment and position prediction.
PredRRPredicted row coordinate from column-wise linear regression. Uses the column position and column regression parameters (ColM, ColB) to estimate where the row coordinate should be if the grid were perfectly aligned. Used for calculating residual errors and detecting misaligned colonies.
PredCCPredicted column coordinate from row-wise linear regression. Uses the row position and row regression parameters (RowM, RowB) to estimate where the column coordinate should be if the grid were perfectly aligned. Used for calculating residual errors and detecting misaligned colonies.
ResidualErrorEuclidean distance between the actual colony centroid and the predicted position from linear regression. Quantifies how far each colony deviates from the expected grid pattern. High values indicate misdetections, off-grid growth, or local plate warping. Used by refinement operations to filter outliers and select the most plausible colony per grid cell.
- Parameters:
section_num (Optional[int])
- __del__()
Automatically stop tracemalloc when the object is deleted.
- measure(image)
Compute grid edges and assign each detected object to a grid cell.
- Parameters:
image – Image with detected objects.
- Returns:
DataFrame with grid assignments (ROW_NUM, COL_NUM, ROW_MAJOR_IDX).
- class phenotypic.measure.MeasureGridSpatial(*args, **kwargs)[source]
Bases:
GridMeasureFeaturesMeasure edge-to-edge distances to neighbors in adjacent grid cells.
For each detected colony, identify the nearest object in the left, right, above, and below grid cells and compute the minimum bounding-box edge-to-edge distance. Edge and corner colonies report
NaNfor directions beyond the plate boundary.- Returns:
pd.DataFrame: Object-level neighbor measurements with columns:
Label: unique object identifier.
LeftNeighborObjLabel, LeftDistance.
RightNeighborObjLabel, RightDistance.
AboveNeighborObjLabel, AboveDistance.
UnderNeighborObjLabel, UnderDistance.
NaNwhere no neighbor exists in a given direction.
- Best For:
Quantifying colony spacing and crowding to assess nutrient competition risk on arrayed plates.
Flagging closely spaced colonies that may cross-contaminate.
Enabling neighbor-aware paired statistical comparisons for competition or cooperation studies.
- Consider Also:
MeasureGridLinRegStatsfor regression-based positional quality metrics.MeasureGridSpreadfor within-well colony dispersion rather than between-well distances.MeasureBoundsfor raw bounding boxes and centroids without neighbor lookups.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of grid-level measurements.
Category: GRID_SPATIAL# Name
Description
LeftNeighborObjLabelThe object label of the left neighbor colony
LeftDistanceThe distance of the left neighbor colony calculated using euclidean distance between bounding boxes
RightNeighborObjLabelThe object label of the right neighbor colony
RightDistanceThe distance of the right neighbor colony calculated using euclidean distance between bounding boxes
AboveNeighborObjLabelThe object label of the above neighbor colony
AboveDistanceThe distance of the above neighbor colony calculated using euclidean distance between bounding boxes
UnderNeighborObjLabelThe object label of the under neighbor colony
UnderDistanceThe distance of the under neighbor colony calculated using euclidean distance between bounding boxes
- __del__()
Automatically stop tracemalloc when the object is deleted.
- measure(image)
Compute grid edges and assign each detected object to a grid cell.
- Parameters:
image – Image with detected objects.
- Returns:
DataFrame with grid assignments (ROW_NUM, COL_NUM, ROW_MAJOR_IDX).
- class phenotypic.measure.MeasureGridSpread(*args, **kwargs)[source]
Bases:
GridMeasureFeaturesQuantify within-well colony dispersion using pairwise centroid distances.
Compute the sum of squared pairwise Euclidean distances between all colony centroids in each grid section. High values indicate multiple dispersed objects within a single well – a sign of over-segmentation, fragmented growth, or invasive spreading.
- Returns:
pd.DataFrame: Section-level statistics sorted by spread (descending) with columns:
count: number of colonies detected in the section.
ObjectSpread: sum of squared pairwise Euclidean distances between colony centroids in the section.
- Best For:
Detecting over-segmented wells where multiple objects were found instead of a single cohesive colony.
Identifying invasive or spreading growth that extends beyond the designated grid position.
Flagging wells with questionable data quality for manual review or exclusion from downstream analysis.
- Consider Also:
MeasureGridSpatialfor between-well neighbor distances rather than within-well dispersion.MeasureGridLinRegStatsfor positional accuracy metrics based on linear regression.MeasureBoundsfor raw centroid positions per colony.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of grid-level measurements.
Category: GRID_SPREAD# Name
Description
ObjectSpreadSum of squared pairwise Euclidean distances between all unique colony pairs within a grid section. Quantifies spatial dispersion of colonies in a grid cell. Higher values indicate greater spread from the section center, suggesting over-segmentation, multi-detections, or colonies growing beyond expected boundaries. Used to identify problematic grid sections requiring refinement or quality review.
- __del__()
Automatically stop tracemalloc when the object is deleted.
- measure(image)
Compute grid edges and assign each detected object to a grid cell.
- Parameters:
image – Image with detected objects.
- Returns:
DataFrame with grid assignments (ROW_NUM, COL_NUM, ROW_MAJOR_IDX).
- class phenotypic.measure.MeasureIntensity(*args, **kwargs)[source]
Bases:
MeasureFeaturesMeasure grayscale intensity statistics of detected colonies.
Compute per-colony intensity metrics from the grayscale channel: integrated intensity, percentiles (min, Q1, median, Q3, max), standard deviation, coefficient of variation, and area-normalized density. These statistics reflect colony optical density, biomass accumulation, and internal heterogeneity.
- Returns:
pd.DataFrame: Object-level intensity statistics with columns:
Label, IntegratedIntensity, MinimumIntensity, MaximumIntensity, MeanIntensity, MedianIntensity.
LowerQuartileIntensity, UpperQuartileIntensity, InterquartileRangeIntensity.
StandardDeviationIntensity, CoefficientVarianceIntensity.
Density (integrated intensity / area), ConvexDensity (integrated intensity / convex area).
- Best For:
Tracking colony growth over time via integrated intensity as an optical-density proxy.
Detecting metabolically stressed or slow-growing colonies through low mean intensity.
Identifying sectored or chimeric colonies by high within-colony intensity variance.
Automated colony picking based on biomass thresholds.
- Consider Also:
MeasureSizefor lightweight area and integrated intensity without full statistics.MeasureColorfor multi-channel color statistics when pigmentation is relevant.MeasureTexturefor surface-roughness features that complement intensity metrics.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data. Measurement Metrics and Their Biological Meaning for interpreting intensity metrics in a biological context.
Category: INTENSITY# Name
Description
IntegratedIntensityThe sum of the object’s pixels
DensityThe ratio of the object’s intensity to the max possible intensity of the object
ConvexDensityThe ratio of the objects intensity to the max possible intensity of the object’s convex hull
MinimumIntensityThe minimum intensity of the object
MaximumIntensityThe maximum intensity of the object
MeanIntensityThe mean intensity of the object
MedianIntensityThe median intensity of the object
StandardDeviationIntensityThe standard deviation of the object
CoefficientVarianceIntensityThe coefficient of variation of the object
LowerQuartileIntensityThe lower quartile intensity of the object
UpperQuartileIntensityThe upper quartile intensity of the object
InterquartileRangeIntensityThe interquartile range of the object
- __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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureShape(*args, **kwargs)[source]
Bases:
MeasureFeaturesMeasure comprehensive morphological characteristics of detected colonies.
Extract geometric metrics from each colony shape: area, perimeter, circularity, convex hull properties, width-based measures, Feret diameters, eccentricity, and best-fit ellipse parameters. The output DataFrame provides a full morphological profile for phenotypic classification and growth-pattern analysis.
- Returns:
pd.DataFrame: Object-level morphological measurements with columns:
Label, Area, Perimeter, Circularity, Compactness, ConvexArea, Solidity, Extent, BboxArea.
MeanRadius, MedianRadius, MaxRadius (distance-transform based).
MinFeretDiameter, MaxFeretDiameter (caliper diameters).
MajorAxisLength, MinorAxisLength, Eccentricity, Orientation.
- Best For:
Distinguishing colony morphotypes (smooth circular wild-type vs wrinkled, branching, or invasive mutants).
Assessing growth symmetry and directionality via eccentricity and orientation.
Detecting invasive or spreading growth through low solidity values.
Morphological clustering for automated strain identification.
- Consider Also:
MeasureSizefor a lightweight area-only measurement when full morphology is not needed.MeasureTexturefor surface roughness and pattern features that complement shape metrics.MeasureBoundsfor bounding box and centroid data without shape statistics.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data. Measurement Metrics and Their Biological Meaning for interpreting shape metrics in a biological context.
Category: SHAPE# Name
Description
AreaTotal number of pixels occupied by the microbial colony. Represents colony biomass and growth extent on agar plates. Larger areas typically indicate more robust growth or longer incubation times.
PerimeterTotal length of the colony’s outer boundary in pixels. Measures colony edge complexity and surface irregularity. Smooth, circular colonies have shorter perimeters relative to their area compared to irregular or filamentous colonies.
CircularityCalculated as \(\frac{4\pi*\text{Area}}{\text{Perimeter}^2}\). Measures how closely a colony approximates a perfect circle (value = 1). Values < 1 indicate irregular colony morphology, which may result from genetic mutations, environmental stress, or mixed microbial populations on agar plates.
ConvexAreaArea of the smallest convex polygon that completely contains the colony. Represents the colony’s “filled-in” appearance if all indentations and holes were removed. Useful for detecting colony spreading patterns or invasive growth characteristics.
MedianRadiusMedian distance from colony center to edge across all directions. Provides a robust measure of typical colony size that is less sensitive to outliers than mean width. Particularly useful for colonies with uneven growth or sectoring.
MeanRadiusAverage distance from colony center to edge across all directions. Represents overall colony expansion rate. In arrayed growth assays, this correlates with microbial fitness and growth kinetics under controlled conditions.
MaxRadiusMaximum distance from colony center to edge across all directions. Represents the furthest extent of colony growth from its center. In arrayed microbial assays, this measurement helps identify asymmetric growth patterns or colonies extending toward neighboring positions.
MinFeretDiameterMinimum caliper diameter - the shortest distance between two parallel tangent lines touching opposite sides of the colony. Represents the narrowest dimension of the colony regardless of orientation. Useful for detecting elongated or irregular colony morphologies and measuring colony width.
MaxFeretDiameterMaximum caliper diameter - the longest distance between two parallel tangent lines touching opposite sides of the colony. Represents the maximum dimension of the colony regardless of orientation. Often exceeds major axis length for irregular shapes and helps quantify maximum colony extent.
EccentricityMeasure of colony elongation, ranging from 0 (perfect circle) to 1 (highly elongated). Values near 0 indicate compact, radially symmetric growth typical of healthy bacterial colonies, while higher values may suggest directional growth, motility, or environmental gradients on the agar surface.
SolidityRatio of actual colony area to its convex hull area (Area/ConvexArea). Values near 1 indicate compact, solid colonies with minimal indentations. Lower values (< 0.9) may indicate invasive growth, colony spreading, or the presence of clearing zones around colonies.
ExtentRatio of colony area to its bounding box area (ObjectArea/BboxArea). Measures how efficiently the colony fills its allocated space. Compact colonies have higher extent values, while spread-out or irregular colonies have lower values.
BboxAreaArea of the smallest rectangle that completely contains the colony. Represents the total spatial shape of the colony including any empty space. In high-throughput assays, this helps assess colony positioning and potential interference with neighboring colonies.
MajorAxisLengthLength of the longest axis of the ellipse that best fits the colony shape. Represents the maximum colony dimension. In arrayed microbial growth, this measurement helps identify colonies that have grown beyond their intended grid positions.
MinorAxisLengthLength of the shortest axis of the ellipse that best fits the colony shape. Represents the minimum colony dimension. Together with major axis length, this helps characterize colony aspect ratio and growth anisotropy.
CompactnessCalculated as \(\frac{\text{Perimeter}^2}{4\pi*\text{Area}}\). Inverse of circularity (ranges from 1 for perfect circles to higher values for irregular shapes). Measures colony shape complexity - compact, circular colonies have values near 1, while irregular or filamentous colonies have much higher values.
OrientationAngle (in radians) between the colony’s major axis and the horizontal axis. Measures colony alignment and growth directionality. Random orientations are typical for most bacterial colonies, while consistent orientations may indicate environmental gradients or mechanical stresses during plating.
- __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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureSize(*args, **kwargs)[source]
Bases:
MeasureFeaturesMeasure colony area and integrated intensity as lightweight size proxies.
Extract two fundamental size metrics per detected colony: pixel area (biomass extent) and integrated grayscale intensity (total brightness, a proxy for optical density). This is a convenience class for rapid size assessment without the overhead of full shape or intensity statistical analysis.
- Returns:
pd.DataFrame: Object-level size measurements with columns:
Label: unique object identifier.
Area: number of pixels occupied by the colony.
IntegratedIntensity: sum of grayscale pixel values (proxy for biomass / optical density).
- Best For:
Quick quality-control screening of colony size distributions.
Time-course growth tracking via area at successive time points.
Filtering colonies by minimum size to exclude debris or aborted growth before downstream measurement.
- Consider Also:
MeasureShapefor comprehensive morphological metrics (circularity, convex hull, Feret diameters).MeasureIntensityfor full intensity statistics (percentiles, variance, coefficient of variation).MeasureGridSpreadfor detecting multi-object wells in arrayed assays.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data. Measurement Metrics and Their Biological Meaning for interpreting size metrics in a biological context.
Category: SIZE# Name
Description
AreaTotal number of pixels occupied by the microbial colony.Larger areas typically indicate more robust growth or longer incubation times.
IntegratedIntensityThe sum of the object's grayscale pixels. Calculated as$sum{pixel values}*area$
- __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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureSymmetricZones(n_annuli: int = 100, pelt_penalty: float = 5.0, symmetry_threshold: float = 0.6666666666666666, n_angular_bins: int = 6, smoothing_window: int = 3, method: Literal['distance', 'intensity'] = 'distance', tau_core: float = 0.9, tau_sparse: float = 0.5, bright_intensity_fraction: float = 0.5, intensity_source: Literal['gray', 'detect_mat'] = 'gray')[source]
Bases:
MeasureFeaturesMeasure colony radial expansion and angular symmetry from the object mask alone.
Quantifies each colony by four scalars derived directly from its binary mask and distance-from-inoculum map — no skeletonization, no branch tracing, no runner outlier flagging. The headline output is
SymmetricRadius, the first radius past the inoculum core at which the per-annulus circular mean resultant length of mask-boundary pixels drops below a tunable symmetry threshold.CoreRadius(PELT changepoint on the radial density profile, identical algorithm toMeasureRadialExpansion) anchors the measurement;MeanExpansionandMaxExpansionsummarise how far growth reached past that core.- Args:
- n_annuli: Number of equal-area annuli used for the radial density
profile and angular analysis. Defaults to 100.
- pelt_penalty: PELT penalty controlling changepoint sensitivity for
core detection. Defaults to 5.0.
- symmetry_threshold: Minimum angular coverage (fraction of angular
bins occupied) for growth to be considered symmetric. Defaults to 4/6 (~0.667); with 6 angular bins this means at least 4 of 6 60-degree sectors must contain mask pixels.
- n_angular_bins: Number of angular bins used to compute the
per-annulus angular coverage diagnostic. Defaults to 36 (10 degree resolution).
- smoothing_window: Moving-average window (in annuli) applied to the
angular R̄ profile before the threshold test. Defaults to 3.
- method: Inoculum centre estimator —
"distance"uses the peak of the Euclidean distance transform,
"intensity"uses the intensity-weighted centroid. Defaults to"distance".- tau_core: Minimum bright-pixel fraction required for an annulus
to be classified as inoculum core in the per-angle outward walk. Defaults to 0.9.
- tau_sparse: Minimum bright-pixel fraction required for an annulus
to be classified as dense branching (the outer edge of the dense zone). Defaults to 0.5.
- bright_intensity_fraction: Fraction of the core’s median intensity
used as the bright/background threshold for zone segmentation. Defaults to 0.5.
- intensity_source: Image array used for the brightness comparison
–
"gray"uses the grayscale,"detect_mat"uses the detection matrix. Defaults to"gray".
- Returns:
pd.DataFrame: Object-level radial symmetry measurements with columns:
ObjectLabel: unique object identifier.
SymmetricRadius_CoreRadius: inoculum core radius (pixels).
SymmetricRadius_SymmetricRadius: first radius past the core where R̄ exceeds the symmetry threshold (pixels).
SymmetricRadius_MeanExpansion: mean boundary-pixel distance beyond the core (pixels, clamped at 0).
SymmetricRadius_MaxExpansion: maximum mask-pixel distance beyond the core (pixels, clamped at 0).
SymmetricRadius_CoreEndRadius: mean per-angle core boundary radius from the bright-fraction outward walk (pixels).
SymmetricRadius_DenseEndRadius: mean per-angle outer radius of the dense branching zone (pixels).
SymmetricRadius_SparseEndRadius: mean per-angle outer radius of the sparse branching zone, capped at the symmetric envelope (pixels).
SymmetricRadius_CoreArea: pixel^2 area of the inoculum core zone integrated across the 360-sector polar polygon.
SymmetricRadius_DenseArea: pixel^2 area of the dense branching zone (annular region between core and dense boundaries).
SymmetricRadius_SparseArea: pixel^2 area of the sparse branching zone (annular region between dense and outer boundaries).
- Best For:
Summarising colony-level radial growth with a single symmetry figure of merit.
Distinguishing uniformly-expanding colonies from those with sectors, lopsided growth, or directional bias.
Comparing wild-type versus mutant expansion phenotypes when the biological question is about the colony envelope, not individual hyphae.
Time-course assays where runner counts are noisy but colony extent is informative.
- Consider Also:
MeasureRadialExpansionwhen you need per-branch statistics (branch counts, outlier runner detection) rather than a single symmetry scalar.MeasureShapefor general morphological descriptors (circularity, eccentricity) that do not require radial analysis.MeasureBoundsfor lightweight bounding-box data without any radial pipeline.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data.
Category: SYMMETRIC_RADIUS# Name
Description
CoreRadiusRadius of the dense inoculum core, determined by PELT changepoint detection on the radial mask-density profile centered on the inoculum. Growth measurements are reported relative to this boundary.
SymmetricRadiusRadial distance from the inoculum centroid at which colony growth ceases to be angularly uniform. Computed as the first radius past the core where the smoothed per-annulus circular mean resultant length of mask-boundary pixels exceeds the symmetry threshold. Equals the colony outer envelope when growth remains symmetric throughout.
MeanExpansionMean distance of mask-boundary pixels from the inoculum centroid, measured from the core boundary outward. Captures the typical radial extent of growth past the inoculum, averaged over all angular directions.
MaxExpansionMaximum distance of any mask pixel from the inoculum centroid, measured from the core boundary outward. Captures the farthest extent of growth past the inoculum.
CoreEndRadiusMean radius of the inoculum core boundary derived from the per-angle bright/background ratio walk. Each of 360 1° angular sectors finds the outer edge of the contiguous core run (bright fraction >= tau_core); the reported value is the mean across sectors. Compare with CoreRadius (the global PELT changepoint) — close agreement indicates a well-formed core.
DenseEndRadiusMean outer radius of the dense branching zone, where mask-bright pixels dominate (bright fraction >= tau_sparse). Per-angle radii are capped at the SymmetricRadius and angularly median-smoothed before averaging.
SparseEndRadiusMean outer radius of the sparse branching zone (= colony envelope inside the symmetric growth front). Equals min(objmask outer envelope, SymmetricRadius) per angle, averaged across 360 sectors.
CoreAreaPixel^2 area of the inoculum core zone, integrated across the 360-sector polar polygon defined by the per-angle core radii.
DenseAreaPixel^2 area of the dense branching zone, the annular region between the per-angle core boundary and dense-branching boundary.
SparseAreaPixel^2 area of the sparse branching zone, the annular region between the per-angle dense boundary and the symmetric-envelope outer boundary.
- Parameters:
- __del__()
Automatically stop tracemalloc when the object is deleted.
- inspect(image: Image | None = None, base_layer: Literal['rgb', 'gray', 'detect_mat'] = 'gray')[source]
Plate-level diagnostic overlay for symmetric-radius measurement.
- Parameters:
image (Image | None) – Detected Image with objmap/objmask. If None, the image cached by the most recent
measure()call is reused.base_layer (Literal['rgb', 'gray', 'detect_mat']) – Which image array to use as the plotly background.
- Returns:
Panel Column layout with a single zoomable plotly figure containing toggleable overlay layers.
- 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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]
- class phenotypic.measure.MeasureTexture(scale: int | List[int] = 5, quant_lvl: Literal[8, 16, 32, 64] = 32, enhance: bool = False, warn: bool = False)[source]
Bases:
MeasureFeaturesMeasure colony surface texture using Haralick features from gray-level co-occurrence matrices.
Compute 13 second-order Haralick texture features per colony at one or more pixel-offset scales, across four directional angles (0, 45, 90, 135 degrees), plus direction-averaged values. These features quantify surface roughness, regularity, and directional patterns that distinguish colony morphotypes.
- Args:
- scale: Pixel offset(s) for the co-occurrence matrix. A single
integer or list of integers. Small values (1–2) capture fine texture; large values (5–10) capture coarse patterns. Default:
5.- quant_lvl: Number of gray-level bins for quantization. Accepted
values:
8,16,32,64. Lower values are faster; higher values preserve texture nuance but are more noise-sensitive. Default:32.- enhance: Rescale each colony’s intensity to [0, 1] before
computing Haralick features. Improves contrast in low-variance regions but can bias cross-colony comparisons. Default:
False.- warn: Emit warnings when Haralick computation fails for
individual colonies (typically very small objects). Default:
False.
- Returns:
pd.DataFrame: Object-level texture measurements with columns:
Label: unique object identifier.
13 Haralick features x 4 angles = 52 directional columns per scale (e.g.,
Contrast-deg000-scale05).13 direction-averaged columns per scale (e.g.,
Contrast-avg-scale05).
- References:
[1] R. M. Haralick, K. Shanmugam, and I. Dinstein, “Textural features for image classification,” IEEE Trans. Syst., Man, Cybern., vol. SMC-3, no. 6, pp. 610–621, Nov. 1973.
- Best For:
Distinguishing smooth wild-type colonies from rough, wrinkled, or sporulated mutants.
Assessing mycelial organization in filamentous fungi (radial vs cottony growth).
Multi-feature phenotypic clustering when combined with size, shape, and color measurements.
- Consider Also:
MeasureShapefor geometric morphology metrics (circularity, Feret diameters) that complement texture.MeasureIntensityfor brightness statistics without spatial co-occurrence information.MeasureColorfor pigmentation-based phenotyping.
- See Also:
Tutorial 7: Measuring and Exporting for a walkthrough of measuring and exporting colony data. Measurement Metrics and Their Biological Meaning for interpreting texture metrics in a biological context.
Category: TEXTURE# Name
Description
AngularSecondMoment- Angular second moment (energy / uniformity). Measures the degree of local homogeneity
(Σ p(i,j)²). High values → uniform texture (e.g., smooth, yeast-like colonies with consistent mycelial density). Low values → heterogeneous surfaces (e.g., sectored, wrinkled, or mixed sporulation zones). Reflects colony surface regularity rather than brightness.
Contrast- Contrast (local intensity variation; Σ (i–j)² p(i,j)). High values indicate strong gray-level
differences (e.g., sharply defined rings, radial sectors, raised or folded regions). Low values indicate gradual tonal changes or uniformly pigmented colonies. Quantifies visual roughness and zonation amplitude.
Correlation- Linear gray-level correlation between neighboring pixels. Positive, high values suggest
structured spatial dependence (e.g., oriented radial hyphae or concentric patterns); near-zero values indicate uncorrelated, disordered growth (e.g., diffuse cottony mycelium). Sensitive to illumination gradients and directional GLCM computation.
HaralickVariance- GLCM variance (Σ (i–μ)² p(i,j)). Captures spread of co-occurring gray-level pairs, distinct
from raw intensity variance. High values → complex, multi-zone textures with variable hyphal/spore densities. Low values → consistent gray-level relationships and simpler colony surfaces.
InverseDifferenceMoment- Homogeneity (Σ p(i,j) / (1 + (i–j)²)). High values → smooth, locally uniform textures
(e.g., glabrous colonies, uniform aerial mycelium). Low values → abrupt gray-level changes (e.g., granular sporulation, wrinkled surfaces). Typically inversely correlated with Contrast.
SumAverage- Mean of gray-level sums (Σ k·p_{x+y}(k)). Reflects the average intensity combination of
neighboring pixels. In fungal colonies, can loosely parallel mean colony brightness when illumination and exposure are controlled, but remains a second-order rather than first-order intensity metric.
SumVariance- Variance of gray-level sum distribution. High values → heterogeneous brightness zones
(e.g., alternating dense/sparse or pigmented/non-pigmented regions). Low values → uniform tone across the colony. Often correlated with Contrast; use comparatively within one setup.
SumEntropy- Entropy of the gray-level sum distribution. High values → diverse brightness combinations
and irregular zonation. Low values → repetitive or periodic brightness patterns (e.g., evenly spaced rings). Indicates spatial unpredictability of summed intensities.
Entropy- Global GLCM entropy (–Σ p(i,j)·log p(i,j)). Measures total texture disorder and information
content. High values → complex, irregular colony surfaces (powdery, fuzzy, or sectored growth). Low values → simple, smooth, predictable patterns (glabrous or uniform colonies). Sensitive to gray-level quantization and image dynamic range.
DiffVariance- Variance of gray-level difference distribution. High values → mixture of smooth and textured
regions (e.g., smooth margins with wrinkled centers). Low values → consistent edge content. Highlights heterogeneity in edge magnitude across the colony.
DiffEntropy- Entropy of gray-level difference distribution. High values → irregular, unpredictable
intensity transitions (e.g., random sporulation or uneven mycelial networks). Low values → regular periodic transitions (e.g., concentric zonation). Reflects randomness of local contrast rather than its magnitude.
InfoCorrelation1- Information measure of correlation 1. Compares joint vs marginal entropies to quantify
mutual dependence between gray levels. Positive values → structured, predictable textures (e.g., organized radial growth); near-zero → independence between adjacent regions. Direction of sign varies with implementation.
InfoCorrelation2- Information measure of correlation 2 (√[1 – exp(–2 (H_xy2–H_xy))]). Always ≥ 0.
Values approaching 1 → strong spatial dependence and organized architecture (e.g., symmetric rings, radial structure). Values near 0 → random, independent patterns. Captures nonlinear organization missed by linear correlation.
- __del__()
Automatically stop tracemalloc when the object is deleted.
- __init__(scale: int | List[int] = 5, quant_lvl: Literal[8, 16, 32, 64] = 32, enhance: bool = False, warn: bool = False)[source]
Initializes an object with specific configurations for scale, quantization level, enhance, and warning behaviors. This constructor ensures that the ‘scale’ parameter is always stored as a list.
- Parameters:
scale (int | List[int]) – A single integer or a list of integers representing the scale configuration. If a single integer is provided, it will be converted into a list containing that integer.
quant_lvl (Literal[8, 16, 32, 64]) – The quantization level. A higher level adds more computational complexity but captures more discrete texture changes. A higher value is not always more meaningful. Think of this like sensitivity to texture. Acceptable values are either 8, 16, 32, or 64.
enhance (bool) – A flag indicating whether to enhance the image before measuring texture. This can increase the amount of detail captured but can bias the measurements in cases where the relative variance between pixel intensities of an object is small.
warn (bool) – A flag indicating whether warnings should be issued.
- 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):
Pass your processed Image (with detected objects) to measure()
The method calls your subclass’s _operate() implementation
Results are validated and returned as a pandas DataFrame
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('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', ...]