Source code for phenotypic.measure._measure_intensity
from __future__ import annotations
from typing import TYPE_CHECKING
from phenotypic.tools_.constants_ import OBJECT
if TYPE_CHECKING:
from phenotypic._core._image import Image
import pandas as pd
from phenotypic.abc_ import MeasureFeatures
from ..tools_.measurement_info_ import INTENSITY
[docs]
class MeasureIntensity(MeasureFeatures):
"""Measure 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:
- :class:`MeasureSize` for lightweight area and integrated
intensity without full statistics.
- :class:`MeasureColor` for multi-channel color statistics when
pigmentation is relevant.
- :class:`MeasureTexture` for surface-roughness features that
complement intensity metrics.
See Also:
:doc:`/tutorials/notebooks/07_measuring_and_exporting` for a
walkthrough of measuring and exporting colony data.
:doc:`/explanation/measurement_metrics_biological_meaning` for
interpreting intensity metrics in a biological context.
"""
_measurement_info_class = INTENSITY
def _operate(self, image: Image) -> pd.DataFrame:
from phenotypic.measure._measure_shape import MeasureShape
from ..tools_.measurement_info_ import SHAPE
intensity_matrix, objmap = image.gray[:].copy(), image.objmap[:].copy()
measurements = {
str(INTENSITY.INTEGRATED_INTENSITY) : self._calculate_sum(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.MINIMUM_INTENSITY) : self._calculate_minimum(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.MAXIMUM_INTENSITY) : self._calculate_maximum(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.MEAN_INTENSITY) : self._calculate_mean(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.MEDIAN_INTENSITY) : self._calculate_median(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.STANDARD_DEVIATION_INTENSITY): self._calculate_stddev(
array=intensity_matrix, objmap=objmap
),
str(
INTENSITY.COEFFICIENT_VARIANCE_INTENSITY
) : self._calculate_coeff_variation(
array=intensity_matrix,
objmap=objmap,
),
str(INTENSITY.Q1_INTENSITY) : self._calculate_q1(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.Q3_INTENSITY) : self._calculate_q3(
array=intensity_matrix, objmap=objmap
),
str(INTENSITY.IQR_INTENSITY) : self._calculate_iqr(
array=intensity_matrix, objmap=objmap
),
}
measurements = pd.DataFrame(measurements)
measurements.insert(
loc=0, column=OBJECT.LABEL, value=image.objects.labels2series()
)
shape_measurements = MeasureShape().measure(image)
measurements[INTENSITY.DENSITY] = (
measurements[INTENSITY.INTEGRATED_INTENSITY]
/ shape_measurements[SHAPE.AREA]
)
measurements[INTENSITY.CONVEX_DENSITY] = (
measurements[INTENSITY.INTEGRATED_INTENSITY]
/ shape_measurements[SHAPE.CONVEX_AREA]
)
return measurements
MeasureIntensity.__doc__ = INTENSITY.append_rst_to_doc(MeasureIntensity)