Source code for phenotypic.refine._grid_oversized_object_remover
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from phenotypic._core._grid_image import GridImage
import numpy as np
from phenotypic.abc_ import GridObjectRefiner
from phenotypic.tools_.constants_ import OBJECT
from phenotypic.tools_.measurement_info_ import BBOX
[docs]
class GridOversizedObjectRemover(GridObjectRefiner):
"""Remove objects whose bounding box exceeds the maximum grid cell dimension.
Compares each object's width and height against the largest cell span in
the grid and discards objects that match or exceed it. Eliminates merged
colonies, agar rim intrusions, and segmentation spillover that span
entire grid cells.
Returns:
Image: Input image with ``objmap`` and ``objmask`` updated to exclude
objects exceeding the grid cell size.
Best For:
- Dropping merged blobs that span adjacent grid positions.
- Removing strong edge artifacts near the plate rim that intrude
into the grid.
- Post-detection cleanup on pinned colony grids where each cell
should contain one confined colony.
Consider Also:
- :class:`GridSectionLargest` when you want to keep the single
largest object per cell rather than removing oversized ones.
- :class:`GridAlignmentRefiner` for full grid-aware dominant-object
selection.
- :class:`SmallObjectRemover` when the problem is undersized debris
rather than oversized detections.
See Also:
:doc:`/how_to/notebooks/refine_noisy_boundaries` for grid-based
refinement workflows.
:doc:`/explanation/refinement_strategies` for an overview of
grid refinement strategies.
"""
def _operate(self, image: GridImage) -> GridImage:
"""
Applies operations on the given GridImage to remove objects based on maximum width and height constraints.
This method processes the grid metadata of a `GridImage` object to identify objects
that exceed the maximum calculated width and height. It sets such objects to a
background value of 0 in the object's mapping array. This helps filter out undesired
large objects in the image.
Args:
image (GridImage): The arr grid image containing grid metadata and object map.
Returns:
GridImage: The processed grid image with specified objects removed.
"""
row_edges = image.grid.get_row_edges()
col_edges = image.grid.get_col_edges()
grid_info = image.grid.info()
# To simplify calculation use the max width & distance
max_width = max(col_edges[1:] - col_edges[:-1])
max_height = max(row_edges[1:] - row_edges[:-1])
# Calculate the width and height of each object
grid_info.loc[:, "width"] = (
grid_info.loc[:, str(BBOX.MAX_CC)] - grid_info.loc[:, str(BBOX.MIN_CC)]
)
grid_info.loc[:, "height"] = (
grid_info.loc[:, str(BBOX.MAX_RR)] - grid_info.loc[:, str(BBOX.MIN_RR)]
)
# Find objects that are past the max height & width
over_width_obj = grid_info.loc[:, "width"] >= max_width
over_height_obj = grid_info.loc[:, "height"] >= max_height
oversized_obj_labels = grid_info.loc[
over_width_obj | over_height_obj, OBJECT.LABEL
].unique()
# Set the target objects to the background val of 0
image.objmap[np.isin(image.objmap[:], oversized_obj_labels)] = 0
return image