acia.segm.filter#

Filters for segmentating overlay objects

acia.segm.filter.bbox_to_rectangle(bbox)[source]#
Parameters:

bbox (tuple[float, float, float, float])

class acia.segm.filter.NMSFilter[source]#

Bases: object

Non-maximum supression filter based on contours

static filter(overlay, iou_thr=0.1, mode='iou')[source]#
Parameters:

overlay (Overlay)

Return type:

Overlay

class acia.segm.filter.SizeFilter[source]#

Bases: object

Filter by contour area

static filter(overlay, min_area, max_area)[source]#

Filter an overlay based on contour sizes

Parameters:
  • overlay (Overlay) – the overlay to filter

  • min_area ([type]) – minimum area of a contour

  • max_area ([type]) – maximum area of a contour

Returns:

Overlay – the filtered overlay

Return type:

Overlay

class acia.segm.filter.EllipsoidFilter[source]#

Bases: object

Contour filter for ellipsoid shape

static filter(overlay, min_width_height_ratio, max_width_height_ratio)[source]#
Parameters:

overlay (Overlay)

Return type:

Overlay

class acia.segm.filter.CellFilter[source]#

Bases: object

Pluggable, physical-unit cell filter for an Overlay.

A CellFilter keeps contours whose backing property (its calibrated value()) falls within a (vmin, vmax) range. The range bounds are pint Quantity objects in physical units (e.g. Q_(2, "um**2")) so the same filter stays valid across cameras with different pixel_size – the per-contour value() is calibrated from the source pixel_size, not measured in raw pixels.

Mirrors PropertyExtractor: adding a new filter is a single small subclass that sets name and overrides value(); there is no central registry. Instances are simply passed in a list to apply_cell_filters().

Variables:
  • name (str) – short identifier for the backing property (e.g. "area").

  • vmin – inclusive lower bound (pint Quantity / number), or None for an open lower bound.

  • vmax – inclusive upper bound (pint Quantity / number), or None for an open upper bound.

name: str = 'cell'#

short identifier for the backing property; overridden by subclasses.

__init__(vmin=None, vmax=None)[source]#

Create a filter with an inclusive (vmin, vmax) range.

Parameters:
  • vmin (Quantity | float | None) – inclusive lower bound as a pint Quantity (physical unit), a plain number for dimensionless properties, or None for an open lower bound.

  • vmax (Quantity | float | None) – inclusive upper bound, analogous to vmin.

Return type:

None

property range: tuple[Quantity | float | None, Quantity | float | None]#

The (vmin, vmax) range driving this filter.

value(cont, *, images)[source]#

Return the calibrated physical value of cont for this filter.

Subclasses derive a raw pixel measurement from cont and convert it to physical units using images.pixel_size.

Parameters:
Returns:

The contour’s property as a pint Quantity.

Raises:

NotImplementedError – always, in the base class.

Return type:

Quantity

accepts(cont, *, images)[source]#

Whether cont falls within the (vmin, vmax) range.

The comparison uses pint, so a dimensionality mismatch between the contour value and a bound (e.g. a µm² value vs a µm bound) raises a pint.DimensionalityError – a deliberate guard against misconfigured filters. None bounds are open on that side.

Parameters:
Returns:

True if the contour’s value is within range.

Return type:

bool

mask(properties)[source]#

Boolean keep-mask over properties, aligned with its row order.

This is the path apply_cell_filters() uses. The values come from the column named after this filter – the one its matching PropertyExtractor already produced – instead of being measured again from the contours, which is both the expensive part and a second, independent implementation of the same measurement.

Parameters:

properties (pd.DataFrame) – an extractor table (see execute()) that contains a column named name.

Return type:

np.ndarray

A row whose value is not finite is always dropped, including by a filter with no bounds at all. nan is what an extractor reports for a contour whose geometry it cannot measure – a collinear outline, a mask with no pixels – and a cell whose length is unknown cannot be asserted to lie within a length range. Dropping it here is what the row-wise filters effectively did before, and it keeps such a detection from surviving a one-sided bound.

Returns:

A boolean np.ndarray of len(properties), True where the row is finite and within the (vmin, vmax) range.

Raises:
  • KeyError – if properties has no column for this filter.

  • pint.DimensionalityError – if a bound’s dimension does not match the column’s – the same guard accepts() provides, applied once per run instead of once per contour.

Parameters:

properties (pd.DataFrame)

Return type:

np.ndarray

class acia.segm.filter.AreaFilter[source]#

Bases: _ExtractorCalibratedFilter

Filter cells by physical area (pixel_size**2 -> µm²).

Reuses AreaEx for calibration, so the range bounds must be areas, e.g. AreaFilter(Q_(2, "um**2"), Q_(20, "um**2")).

name: str = 'area'#

short identifier for the backing property; overridden by subclasses.

class acia.segm.filter.LengthFilter[source]#

Bases: _ExtractorCalibratedFilter

Filter cells by physical length (major axis, pixel_size -> µm).

Length is the longer edge of the contour’s minimum rotated bounding box, computed exactly like LengthEx.

name: str = 'length'#

short identifier for the backing property; overridden by subclasses.

class acia.segm.filter.WidthFilter[source]#

Bases: _ExtractorCalibratedFilter

Filter cells by physical width (minor axis, pixel_size -> µm).

Width is the shorter edge of the contour’s minimum rotated bounding box, computed exactly like WidthEx.

name: str = 'width'#

short identifier for the backing property; overridden by subclasses.

class acia.segm.filter.CircularityFilter[source]#

Bases: CellFilter

Filter cells by circularity (dimensionless, 4*pi*area / perimeter**2).

Computed exactly like CircularityEx. Bounds are dimensionless (plain floats or dimensionless Quantity), e.g. CircularityFilter(vmin=0.8).

name: str = 'circularity'#

short identifier for the backing property; overridden by subclasses.

value(cont, *, images)[source]#

Return the calibrated physical value of cont for this filter.

Subclasses derive a raw pixel measurement from cont and convert it to physical units using images.pixel_size.

Parameters:
Returns:

The contour’s property as a pint Quantity.

Raises:

NotImplementedError – always, in the base class.

Return type:

Quantity

class acia.segm.filter.BoundaryClosenessFilter[source]#

Bases: CellFilter

Drop cells whose bounding box lies near any image border.

The value() is the minimum distance (in physical units) from the contour’s bounding box to any of the four image borders, using the source size_h / size_w and pixel_size. The range is (min_distance, None) so cells closer than min_distance to a border are dropped.

name: str = 'boundary_closeness'#

short identifier for the backing property; overridden by subclasses.

__init__(min_distance)[source]#

Create the filter.

Parameters:

min_distance (Quantity) – minimum allowed distance from any image border as a pint length Quantity (e.g. Q_(1, "um")).

Return type:

None

value(cont, *, images)[source]#

Return the calibrated physical value of cont for this filter.

Subclasses derive a raw pixel measurement from cont and convert it to physical units using images.pixel_size.

Parameters:
Returns:

The contour’s property as a pint Quantity.

Raises:

NotImplementedError – always, in the base class.

Return type:

Quantity

acia.segm.filter.apply_cell_filters(overlay, filters, *, properties)[source]#

Keep contours accepted by ALL filters, preserving the overlay time model.

properties is the table an ExtractorExecutor already produced for this overlay. Each filter reads its own column from it, so the contours are measured once (during extraction) rather than a second time here. Calibration comes from the table’s units, which is why no image source is needed.

Parameters:
  • overlay (Overlay) – the overlay to filter.

  • filters (Sequence[CellFilter]) – the cell filters to apply; a contour is kept iff every filter accepts it (logical AND). An empty filter list keeps everything.

  • properties (pd.DataFrame) – the extractor table describing overlay, indexed by contour id. Every filter needs a column named after it.

Returns:

A new Overlay with the kept contours and the same time model (timepoints / frame_interval). The result may be empty.

Raises:
  • ValueError – if properties does not describe every contour.

  • KeyError – if a filter has no matching column in properties.

Return type:

Overlay