tlc.data_types.segmentation

Defines representations of instance segmentation data in 3LC.

Module Contents

Classes

Class

Description

CocoRle

A dictionary representation of a COCO RLE.

SegmentationMasks

Container for mask-based instance segmentation.

SegmentationPolygons

Container for polygon-based instance segmentation.

Data

Data

Description

SegmentationMasksFormat

API

class CocoRle

Bases: typing.TypedDict

A dictionary representation of a COCO RLE.

Initialize self. See help(type(self)) for accurate signature.

counts: bytes = None
size: list[int] = None

The size of the image in pixels.

class SegmentationMasks

Bases: tlc.data_types._geometry_base.GeometryBase

Container for mask-based instance segmentation.

Axis order — important. Masks are stored as a (H, W, N) uint8 array (height, width, instance index). This differs from the PyTorch / Mask R-CNN convention of (N, H, W). Use mask_format="nhw" on the constructor to supply PyTorch-style input — it gets transposed to (H, W, N) once during __post_init__. Read access (seg.masks) always returns the native (H, W, N) layout.

Per-instance metadata (labels, confidences, etc.) is stored in per_instance_extras.

Objects can be created in two ways:

  1. Direct construction: Pass all data at once.

  2. Build incrementally: Use create_empty() and add_instance().

Example:

import numpy as np

# Direct construction (native (H, W, N) layout)
masks = np.zeros((480, 640, 2), dtype=np.uint8)
masks[10:50, 10:50, 0] = 1
masks[100:200, 100:200, 1] = 1
seg = SegmentationMasks(
    image_width=640,
    image_height=480,
    masks=masks,
    labels=[1, 2],
)

# Direct construction from PyTorch-style (N, H, W) input
nhw = np.zeros((2, 480, 640), dtype=np.uint8)
seg = SegmentationMasks(
    image_width=640, image_height=480, masks=nhw, mask_format="nhw", labels=[1, 2],
)

# Build incrementally — single (H, W) masks, no axis ambiguity
seg = SegmentationMasks.create_empty(image_width=640, image_height=480)
mask = np.zeros((480, 640), dtype=np.uint8)
mask[10:50, 10:50] = 1
seg.add_instance(mask=mask, label=1)

# Serialization — masks are RLE-encoded into the row, decoded back on read
row = seg.to_row()
seg = SegmentationMasks.from_row(row)
add_instance(
*,
mask: ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single mask instance.

Parameters:
  • mask – A 2D (H, W) binary mask for this instance.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_instance_extras – Optional dictionary of per-instance attributes. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If the mask shape does not match (image_height, image_width).

classmethod create_empty(
*,
image_width: int,
image_height: int,
) SegmentationMasks

Create an empty SegmentationMasks object to build up incrementally.

Parameters:
  • image_width – Width of the image in pixels (required for correct empty mask shape).

  • image_height – Height of the image in pixels (required for correct empty mask shape).

Returns:

An empty SegmentationMasks object ready for adding instances.

image_height: int = 0
image_width: int = 0
mask_format: InitVar['hwn' | 'nhw'] = hwn

Layout of the input masks array. Storage is always "hwn" ((H, W, N)).

Use "nhw" for PyTorch / Mask R-CNN style (N, H, W) inputs. Only matters for 3D inputs; a 2D (H, W) mask is unambiguously a single instance.

masks: ndarray = field(...)

(H, W, N) uint8 array of binary masks. Native storage layout.

For PyTorch-style (N, H, W) input pass mask_format="nhw" to the constructor; masks are transposed to the native layout once during __post_init__.

property num_instances: int

Return the number of instances.

classmethod schema(
classes: str | Sequence[str] | Sequence[dict[str, str]] | Sequence[MapElement] | dict[float, str] | dict[int, str] | dict[float, MapElement] | dict[int, MapElement] | None = None,
*,
include_per_instance_confidence: bool = False,
include_is_crowd: bool = False,
display_name: str = '',
description: str = '',
writable: bool = True,
default_visible: bool = True,
display_importance: float = 0,
per_instance_schemas: dict[str, Schema] | None = None,
) Schema

Build the column Schema describing mask-based instance segmentation.

Parameters:
  • classes – A class map for per-instance labels, or None to skip labels.

  • include_per_instance_confidence – Whether to add a per-instance confidence field.

  • include_is_crowd – Whether to add an is_crowd field.

  • display_name – Column display name in the Dashboard.

  • description – Column description.

  • writable – Whether the column is editable in the Dashboard.

  • default_visible – Whether the column is visible by default.

  • display_importance – Ordering weight for column display.

  • per_instance_schemas – Custom per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

SegmentationMasksFormat = None
class SegmentationPolygons

Bases: tlc.data_types._geometry_base.GeometryBase

Container for polygon-based instance segmentation.

Each instance has one polygon (list of alternating x,y coords). Per-instance metadata (labels, confidences, etc.) is stored in per_instance_extras.

Objects can be created in two ways:

  1. Direct construction: Pass all data at once.

  2. Build incrementally: Use create_empty() and add_instance().

Example:

import numpy as np

# Direct construction
seg = SegmentationPolygons(
    image_width=640,
    image_height=480,
    polygons=[[10.0, 20.0, 50.0, 20.0, 30.0, 60.0]],
    labels=[1],
)

# Build incrementally
seg = SegmentationPolygons.create_empty(image_width=640, image_height=480)
seg.add_instance(
    polygon=[10.0, 20.0, 50.0, 20.0, 30.0, 60.0],
    label=1,
)

# Serialization — convert to/from 3LC Table row format
# Default ``from_row`` returns absolute pixel coords; call ``.to_relative()`` for [0, 1] output.
# When reading via ``table[i][col]``, ``Schema.from_row`` honors the schema's ``relative=``
# setting automatically and applies ``.to_relative()`` on your behalf when set.
row = seg.to_row()
seg = SegmentationPolygons.from_row(row).to_relative()
add_instance(
*,
polygon: list[float] | ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single polygon instance.

Parameters:
  • polygon – Flat list of alternating x,y coordinates. Must have even length >= 6 (at least 3 points).

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_instance_extras – Optional dictionary of per-instance attributes. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If the polygon has fewer than 6 coordinates or odd length.

classmethod create_empty(
*,
image_width: int = 0,
image_height: int = 0,
) SegmentationPolygons

Create an empty SegmentationPolygons object to build up incrementally.

Parameters:
  • image_width – Width of the image in pixels.

  • image_height – Height of the image in pixels.

Returns:

An empty SegmentationPolygons object ready for adding instances.

image_height: int = 0
image_width: int = 0
property num_instances: int

Return the number of instances.

polygons: list[list[float]] = field(...)

Per-instance polygons, list[list[float]] (alternating x, y coords) after coercion. The constructor also accepts an ndarray of shape (num_instances, 2*num_points); __post_init__ converts it to list-of-lists. Use the list form (or pre-convert with [list(map(float, p)) for p in arr]) to satisfy strict type checking.

relative: bool = False

Whether polygons are in relative [0, 1] coords (True) or absolute pixel coords (False, default). Naming matches the schema’s relative= kwarg and the value type’s polygons_are_relative flag.

from_row returns absolute pixel coords by default; the schema’s polygons_are_relative flag (set via Schema(..., relative=True)) is honored by Schema.from_row and causes a final to_relative() to be applied. On write, to_row reads this field to know whether to scale up before RLE-encoding.

classmethod schema(
classes: str | Sequence[str] | Sequence[dict[str, str]] | Sequence[MapElement] | dict[float, str] | dict[int, str] | dict[float, MapElement] | dict[int, MapElement] | None = None,
*,
relative: bool = False,
include_per_instance_confidence: bool = False,
include_is_crowd: bool = False,
display_name: str = '',
description: str = '',
writable: bool = True,
default_visible: bool = True,
display_importance: float = 0,
per_instance_schemas: dict[str, Schema] | None = None,
) Schema

Build the column Schema describing polygon-based instance segmentation.

Parameters:
  • classes – A class map for per-instance labels, or None to skip labels.

  • relative – Stores the column’s preferred coordinate convention on the value type (polygons_are_relative). When reading through the schema (e.g. table[i][col]), tlc.Schema.from_row() honors this flag and applies SegmentationPolygons.to_relative automatically. Direct calls to SegmentationPolygons.from_row skip the schema and always return absolute coords; call .to_relative() on the result if you need normalized output.

  • include_per_instance_confidence – Whether to add a per-instance confidence field.

  • include_is_crowd – Whether to add an is_crowd field.

  • display_name – Column display name in the Dashboard.

  • description – Column description.

  • writable – Whether the column is editable in the Dashboard.

  • default_visible – Whether the column is visible by default.

  • display_importance – Ordering weight for column display.

  • per_instance_schemas – Custom per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

to_absolute() SegmentationPolygons

Return a copy with polygons in absolute pixel coordinates.

Idempotent: returns self unchanged when already in pixel coords.

Raises:

ValueError – If image_width or image_height is not positive.

to_relative() SegmentationPolygons

Return a copy with polygons in relative [0, 1] coordinates.

Idempotent: returns self unchanged when already relative.

Raises:

ValueError – If image_width or image_height is not positive.