tlc.data_types

Data-bearing types for working with 3LC Table data.

This package hosts Python-side container classes and lightweight typing helpers for common table features (keypoints, oriented bounding boxes, segmentation, and bounding boxes).

Package Contents

Classes

Class

Description

BoundingBoxes2D

Container for 2D axis-aligned bounding boxes.

BoundingBoxes3D

Container for 3D axis-aligned bounding boxes.

CocoRle

A dictionary representation of a COCO RLE.

Geometry2D

Container for 2D geometry instances — the general form.

Geometry2DBase

Base class for 2D geometry containers.

Geometry3D

Container for 3D geometry instances — the general form.

Geometry3DBase

Base class for 3D geometry containers.

GeometryBase

Abstract base class for all geometry instance containers.

Keypoints2D

Container for 2D keypoint instances.

OrientedBoundingBoxes2D

Container for 2D oriented bounding boxes.

OrientedBoundingBoxes3D

Container for 3D oriented bounding boxes.

SegmentationMasks

Container for mask-based instance segmentation.

SegmentationPolygons

Container for polygon-based instance segmentation.

Functions

Function

Description

legacy_bb_row_to_bounding_boxes_2d

Convert a legacy BB row to a BoundingBoxes2D.

API

class BoundingBoxes2D

Bases: tlc.data_types._geometry_base.Geometry2DBase

Container for 2D axis-aligned bounding boxes.

Storage: (N, 4) array with [x_min, y_min, x_max, y_max] per box. Serialization is handled by the bounding_boxes_2d sample type.

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
bounding_boxes = BoundingBoxes2D(
    bounding_boxes=np.array([
        [10, 10, 100, 100],
        [50, 50, 150, 150],
        [200, 100, 300, 250],
    ], dtype=np.float32),
    labels=[0, 1, 0],
    confidences=[0.95, 0.88, 0.92],
    image_width=640,
    image_height=480,
)

# Build incrementally
bounding_boxes = BoundingBoxes2D.create_empty(image_width=640, image_height=480)
bounding_boxes.add_instance(bounding_box=[10, 20, 100, 120], label=0, confidence=0.95)

# COCO / YOLO input — converted to xyxy in __post_init__
bounding_boxes = BoundingBoxes2D(
    bounding_boxes=coco_xywh, bounding_box_format="xywh", image_width=640, image_height=480,
)

# YOLO normalized cxywh — denormalized to absolute xyxy
bounding_boxes = BoundingBoxes2D(
    bounding_boxes=yolo_cxywh, bounding_box_format="cxywh", normalized=True,
    image_width=640, image_height=480,
)

# Serialization — convert to/from 3LC Table row format
row = bounding_boxes.to_row()
bounding_boxes = BoundingBoxes2D.from_row(row)
add_instance(
*,
bounding_box: list[float] | tuple[float, float, float, float] | ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single bounding box instance to the object.

Parameters:
  • bounding_box – Bounding box in xyxy format [x_min, y_min, x_max, y_max]. Can be provided as a list, tuple, or numpy array with 4 elements.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_instance_extras – Optional dictionary of per-instance attributes (e.g., {"track_id": 42, "area": 1500}). Values should be scalars. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If the bounding_box does not have exactly 4 elements.

Example:

bounding_boxes = BoundingBoxes2D.create_empty(image_width=640, image_height=480)
bounding_boxes.add_instance(bounding_box=[10, 20, 100, 120], label=0, confidence=0.95)
bounding_boxes.add_instance(
    bounding_box=[200, 150, 350, 300],
    label=1,
    confidence=0.88,
    per_instance_extras={"track_id": 42},
)
bounding_box_format: InitVar['xyxy' | 'xywh' | 'cxywh'] = xyxy

Format of the input bounding_boxes array. Storage is always "xyxy" regardless.

Use "xywh" for COCO-style [x_min, y_min, width, height] or "cxywh" for YOLO-style [cx, cy, width, height].

bounding_boxes: ndarray[tuple[int, int], dtype[numpy.float32]] = field(...)

A numpy array of shape (num_instances, 4). Always stored as [x_min, y_min, x_max, y_max] (xyxy).

The constructor accepts other formats via bounding_box_format= and normalizes to xyxy in __post_init__. Direct attribute assignment (bb.bounding_boxes = ...) bypasses normalization — pre-convert with xywh_to_xyxy / cxywh_to_xyxy from tlc.data_types._bb_conversions.

property bounding_boxes_cxywh: ndarray

Return the bounding boxes in centered xywh format.

Converts from the internal xyxy format [x_min, y_min, x_max, y_max] to centered xywh format [center_x, center_y, width, height], which is commonly used by YOLO-style frameworks.

Returns:

A numpy array of shape (num_instances, 4) with bounding boxes in [cx, cy, w, h] format.

property bounding_boxes_xywh: ndarray

Return the bounding boxes in xywh format.

Converts from the internal xyxy format [x_min, y_min, x_max, y_max] to xywh format [x_min, y_min, width, height], which is commonly used by some training frameworks (e.g. COCO).

Returns:

A numpy array of shape (num_instances, 4) with bounding boxes in [x, y, width, height] format.

classmethod create_empty(
*,
image_width: float | None = None,
image_height: float | None = None,
x_min: float | None = None,
y_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
) BoundingBoxes2D

Create an empty BoundingBoxes2D object to build up incrementally.

Useful for creating bounding box data from scratch by adding instances one at a time using add_instance().

Parameters:
  • image_width – Convenience parameter, sets x_max = x_min + image_width.

  • image_height – Convenience parameter, sets y_max = y_min + image_height.

  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • x_max – Maximum x coordinate (optional, provide this OR image_width if specifying bounds).

  • y_max – Maximum y coordinate (optional, provide this OR image_height if specifying bounds).

Returns:

An empty BoundingBoxes2D object ready for adding instances.

Example:

bounding_boxes = BoundingBoxes2D.create_empty(image_width=640, image_height=480)
bounding_boxes.add_instance(bounding_box=[10, 20, 100, 120], label=0, confidence=0.95)
classmethod from_legacy_row(
row: Mapping[str, Any],
schema: Schema,
) BoundingBoxes2D

Construct a BoundingBoxes2D from a legacy bb_list-format row.

Bridges old-format table data (bb_list with x0/y0/x1/y1 dicts) to the new geometry-based representation. The coordinate format (XYXY, XYWH, centered-XYWH) and normalization are auto-detected from the schema’s number roles.

Parameters:
  • row – Row dict with keys "image_width", "image_height", "bb_list".

  • schema – The column-level schema (must contain a "bb_list" sub-schema whose number roles determine the coordinate format).

Returns:

A BoundingBoxes2D in absolute XYXY format with bounds set from image dimensions.

image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

normalized: InitVar[bool] = False

Whether the input bounding_boxes coordinates are normalized to [0, 1].

When True, coordinates are denormalized to absolute pixel values using the image dimensions derived from bounds (x_max/y_max). Bounds must be set. Applied after bounding_box_format conversion.

property num_instances: int

Return the number of bounding box 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,
x_min_default: float | None = None,
y_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
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 2D axis-aligned bounding boxes.

Parameters:
  • classes – A class map (list of names, dict of numeric keys to names or MapElements, or a single class name) for per-instance labels, or None to skip labels.

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

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • 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 – Additional per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

class BoundingBoxes3D

Bases: tlc.data_types._geometry_base.Geometry3DBase

Container for 3D axis-aligned bounding boxes.

Storage: (N, 6) array with [x_min, y_min, z_min, x_max, y_max, z_max] per box. Serialization is handled by the bounding_boxes_3d sample type.

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
bounding_boxes = BoundingBoxes3D(
    bounding_boxes=np.array([
        [0, 0, 0, 1, 1, 1],
        [2, 2, 2, 4, 4, 4],
        [5, 5, 5, 8, 8, 8],
    ], dtype=np.float32),
    labels=[0, 1, 0],
    confidences=[0.95, 0.88, 0.92],
    x_max=10.0,
    y_max=10.0,
    z_max=10.0,
)

# Build incrementally
bounding_boxes = BoundingBoxes3D.create_empty(x_max=10, y_max=10, z_max=10)
bounding_boxes.add_instance(bounding_box=[0, 0, 0, 1, 2, 3], label=0, confidence=0.95)

# Top-corner + size input — converted to xyzxyz in __post_init__
bounding_boxes = BoundingBoxes3D(
    bounding_boxes=corner_size, bounding_box_format="xyzwhd", x_max=10, y_max=10, z_max=10,
)

# Normalized input — denormalized to absolute coordinates
bounding_boxes = BoundingBoxes3D(
    bounding_boxes=norm_xyzxyz, normalized=True, x_max=10, y_max=10, z_max=10,
)

# Serialization — convert to/from 3LC Table row format
row = bounding_boxes.to_row()
bounding_boxes = BoundingBoxes3D.from_row(row)
add_instance(
*,
bounding_box: list[float] | tuple[float, float, float, float, float, float] | ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single bounding box instance to the object.

Parameters:
  • bounding_box – Bounding box in format [x_min, y_min, z_min, x_max, y_max, z_max]. Can be provided as a list, tuple, or numpy array with 6 elements.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_instance_extras – Optional dictionary of per-instance attributes (e.g., {"track_id": 42, "volume": 1500}). Values should be scalars. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If the bounding_box does not have exactly 6 elements.

bounding_box_format: InitVar['xyzxyz' | 'xyzwhd'] = xyzxyz

Format of the input bounding_boxes array. Storage is always "xyzxyz" regardless.

Use "xyzwhd" for [x_min, y_min, z_min, width, height, depth] (top-corner + size).

bounding_boxes: ndarray[tuple[int, int], dtype[numpy.float32]] = field(...)

A numpy array of shape (num_instances, 6). Always stored as [x_min, y_min, z_min, x_max, y_max, z_max] (xyzxyz). Use bounding_box_format= to supply other layouts at construction time.

property bounding_boxes_xyzwhd: ndarray

Return the bounding boxes in xyzwhd format.

Converts from the internal format [x_min, y_min, z_min, x_max, y_max, z_max] to [x_min, y_min, z_min, width, height, depth] format.

Returns:

A numpy array of shape (num_instances, 6) with bounding boxes in [x, y, z, w, h, d] format.

classmethod create_empty(
*,
x_min: float | None = None,
y_min: float | None = None,
z_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
z_max: float | None = None,
) BoundingBoxes3D

Create an empty BoundingBoxes3D object to build up incrementally.

Useful for creating bounding box data from scratch by adding instances one at a time using add_instance().

Parameters:
  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • z_min – Minimum z coordinate (optional).

  • x_max – Maximum x coordinate (optional).

  • y_max – Maximum y coordinate (optional).

  • z_max – Maximum z coordinate (optional).

Returns:

An empty BoundingBoxes3D object ready for adding instances.

image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

normalized: InitVar[bool] = False

Whether the input bounding_boxes coordinates are normalized to [0, 1].

When True, coordinates are denormalized to absolute values using the dimensions derived from bounds (x_max/y_max/z_max). Bounds must be set. Applied after bounding_box_format conversion.

property num_instances: int

Return the number of bounding box 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,
x_min_default: float | None = None,
y_min_default: float | None = None,
z_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
z_max_default: float | None = None,
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 3D axis-aligned bounding boxes.

Parameters:
  • classes – A class map (list of names, dict of numeric keys to names or MapElements, or a single class name) for per-instance labels, or None to skip labels.

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

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • z_min_default – Default scene z_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • z_max_default – Default scene z_max bound.

  • 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 – Additional per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

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 Geometry2D

Bases: tlc.data_types._geometry_base.Geometry2DBase

Container for 2D geometry instances — the general form.

Supports all primitives: vertices, lines, triangles, axis-aligned bounding boxes (bounding_boxes, stored xyxy), and oriented bounding boxes (obbs). Each storage list holds one per-instance numpy array; num_instances is determined from the consistent length across all non-empty per-instance lists. The specialized classes (BoundingBoxes2D, Keypoints2D, OrientedBoundingBoxes2D) are narrower forms with a single primary array.

Serialization is handled by the geometry_2d sample type.

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 — one instance with vertices + an axis-aligned bounding box
g = Geometry2D(
    vertices=[np.array([0, 0, 10, 0, 5, 10], dtype=np.float32)],
    bounding_boxes=[np.array([[0, 0, 10, 10]], dtype=np.float32)],
    labels=[3],
    confidences=[0.9],
    x_max=100, y_max=100,
)

# Build incrementally — promoted `label`/`confidence` like the specialized classes
g = Geometry2D.create_empty(x_max=100, y_max=100)
g.add_instance(
    vertices=np.array([[0, 0], [10, 0], [5, 10]], dtype=np.float32),
    lines=np.array([0, 1, 1, 2], dtype=np.int32),
    triangles=np.array([0, 1, 2], dtype=np.int32),
    label=3,
    confidence=0.9,
)

# COCO/YOLO-format bounding box input — converted to xyxy in __post_init__
g = Geometry2D(vertices=..., bounding_boxes=[xywh_arr], bounding_box_format="xywh")

# Serialization
row = g.to_row()
g = Geometry2D.from_row(row)

Note

Extras (per_point, per_line, per_triangle, per_instance) support scalars, fixed-size arrays, and composite Python objects (e.g., dicts).

add_instance(
*,
vertices: ndarray | str,
lines: ndarray | str | None = None,
triangles: ndarray | str | None = None,
bounding_boxes: ndarray | None = None,
obbs: ndarray | None = None,
label: int | None = None,
confidence: float | None = None,
per_vertex_extras: Mapping[str, ndarray | str] | None = None,
per_line_extras: Mapping[str, ndarray | str] | None = None,
per_triangle_extras: Mapping[str, ndarray | str] | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a 2D instance.

Parameters:
  • vertices – Array of shape (N, 2) or flattened (2N,), dtype float32. In externalized mode, a URL string referencing a pre-existing chunk file.

  • per_vertex_extras – Dict of arrays of shape (N,). In externalized mode, dict of URL strings.

  • per_instance_extras – Dict of scalar per-instance attributes (one value or length-1 array).

  • lines – Flattened int array (2L,) of vertex indices forming L line segments. In externalized mode, a URL string.

  • triangles – Flattened int array (3T,) of vertex indices forming T triangles. In externalized mode, a URL string.

  • bounding_boxes – Array of shape (B, 4) or flattened (4B,), dtype float32. Not supported in externalized mode.

  • obbs – Array of shape (O, 5) or flattened (5O,), dtype float32. Not supported in externalized mode.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_line_extras – Dict of arrays of shape (L,) for per-line extras. In externalized mode, dict of URL strings.

  • per_triangle_extras – Dict of arrays of shape (T,) for per-triangle extras. In externalized mode, dict of URL strings.

Raises:

ValueError – On shape/type/index validation errors, or on mixing externalized/materialized modes.

bounding_box_format: InitVar['xyxy' | 'xywh' | 'cxywh'] = xyxy

Format of the input bounding_boxes arrays. Storage is always "xyxy". Applies to every instance’s bounding_boxes array uniformly. obbs is unaffected.

bounding_boxes: list[ndarray] = field(...)

List of (Bi, 4) float32 arrays. Always stored as [x_min, y_min, x_max, y_max] (xyxy).

Use bounding_box_format= on the constructor to supply "xywh" (COCO) or "cxywh" (YOLO) input; conversion is applied to every instance’s array.

classmethod create_empty(
*,
x_min: float | None = None,
y_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
) Geometry2D

Create an empty Geometry2D container.

Parameters:
  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • x_max – Maximum x coordinate (optional).

  • y_max – Maximum y coordinate (optional).

image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

lines: list[ndarray] = field(...)

List of line index arrays per instance

normalized: InitVar[bool] = False

Whether the input coordinates (vertices, bounding_boxes, obbs) are normalized to [0, 1].

When True, all spatial coordinates are denormalized to absolute pixel values using the image dimensions derived from bounds. Rotation in obbs is not affected. Bounds must be set. Applied after bounding_box_format conversion.

property num_instances: int

Return the number of geometry instances.

obbs: list[ndarray] = field(...)

List of (Oi, 5) float32 arrays [cx, cy, w, h, rotation]

per_line_extras: dict[str, list[ndarray]] = field(...)

Per-line additional data

per_triangle_extras: dict[str, list[ndarray]] = field(...)

Per-triangle additional data

per_vertex_extras: dict[str, list[ndarray]] = field(...)

Per-vertex additional data

classmethod schema(
*,
per_vertex_schemas: dict[str, Schema] | None = None,
per_line_schemas: dict[str, Schema] | None = None,
per_triangle_schemas: dict[str, Schema] | None = None,
per_instance_schemas: dict[str, Schema] | None = None,
is_bulk_data: bool = False,
x_min_default: float | None = None,
y_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
display_name: str = '',
description: str = '',
writable: bool = True,
default_visible: bool = True,
display_importance: float = 0,
) Schema

Build the column Schema describing a 2D geometry scene.

Parameters:
  • per_vertex_schemas – Additional attributes attached to each 2D vertex.

  • per_line_schemas – Additional attributes attached to each line.

  • per_triangle_schemas – Additional attributes attached to each triangle.

  • per_instance_schemas – Additional attributes attached per instance.

  • is_bulk_data – Declares that the data is bulk data.

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • 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.

Returns:

A column schema describing the serialized form of this class.

triangles: list[ndarray] = field(...)

List of triangle index arrays per instance

vertices: list[ndarray] = field(...)

List of flattened vertex arrays per instance

class Geometry2DBase

Bases: tlc.data_types._geometry_base.GeometryBase

Base class for 2D geometry containers.

Provides 2D bounds (x_min, y_min, x_max, y_max). All bounds are optional (float | None).

property bounds: tuple[float | None, float | None, float | None, float | None]

Return the 2D bounds as a tuple (x_min, y_min, x_max, y_max).

property bounds_height: float | None

Height spanned by the bounds, i.e. y_max - (y_min or 0). None if y_max is unset.

property bounds_width: float | None

Width spanned by the bounds, i.e. x_max - (x_min or 0). None if x_max is unset.

x_max: float | None = field(...)

Maximum x coordinate of the coordinate system (optional).

x_min: float | None = field(...)

Minimum x coordinate of the coordinate system (optional).

y_max: float | None = field(...)

Maximum y coordinate of the coordinate system (optional).

y_min: float | None = field(...)

Minimum y coordinate of the coordinate system (optional).

class Geometry3D

Bases: tlc.data_types._geometry_base.Geometry3DBase

Container for 3D geometry instances — the general form.

Supports all primitives: vertices, lines, triangles, axis-aligned bounding boxes (bounding_boxes, stored xyzxyz), and oriented bounding boxes (obbs). Each storage list holds one per-instance numpy array; num_instances is determined from the consistent length across all non-empty per-instance lists. The specialized classes (BoundingBoxes3D, OrientedBoundingBoxes3D) are narrower forms with a single primary array.

Serialization is handled by the geometry_3d sample type.

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 — one instance with vertices + an AABB
g = Geometry3D(
    vertices=[np.array([0, 0, 0, 1, 1, 1], dtype=np.float32)],
    bounding_boxes=[np.array([[0, 0, 0, 1, 1, 1]], dtype=np.float32)],
    labels=[1],
    confidences=[0.9],
    x_max=10, y_max=10, z_max=10,
)

# Build incrementally
g = Geometry3D.create_empty(x_max=10, y_max=10, z_max=10)
g.add_instance(
    vertices=np.array([[0, 0, 0], [1, 1, 1]], dtype=np.float32),
    label=1,
    confidence=0.9,
)

# Top-corner + size bounding box input — converted to xyzxyz in __post_init__
g = Geometry3D(vertices=..., bounding_boxes=[corner_size], bounding_box_format="xyzwhd")

# Serialization
row = g.to_row()
g = Geometry3D.from_row(row)

Note

Extras (per_point, per_line, per_triangle, per_instance) support scalars, fixed-size arrays, and composite Python objects (e.g., dicts).

add_instance(
*,
vertices: ndarray | str,
lines: ndarray | str | None = None,
triangles: ndarray | str | None = None,
bounding_boxes: ndarray | None = None,
obbs: ndarray | None = None,
label: int | None = None,
confidence: float | None = None,
per_vertex_extras: Mapping[str, ndarray | str] | None = None,
per_line_extras: Mapping[str, ndarray | str] | None = None,
per_triangle_extras: Mapping[str, ndarray | str] | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a 3D instance.

Parameters:
  • vertices – Array of shape (N, 3) or flattened (3N,), dtype float32. In externalized mode, a URL string referencing a pre-existing chunk file.

  • lines – Flattened int array (2L,) of vertex indices forming L line segments. In externalized mode, a URL string.

  • triangles – Flattened int array (3T,) of vertex indices forming T triangles. In externalized mode, a URL string.

  • bounding_boxes – Array of shape (B, 6) or flattened (6B,), dtype float32. Not supported in externalized mode.

  • obbs – Array of shape (O, 9) or flattened (9O,), dtype float32. Not supported in externalized mode.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_vertex_extras – Dict of arrays of shape (N,). In externalized mode, dict of URL strings.

  • per_line_extras – Dict of arrays of shape (L,) for per-line extras. In externalized mode, dict of URL strings.

  • per_triangle_extras – Dict of arrays of shape (T,) for per-triangle extras. In externalized mode, dict of URL strings.

  • per_instance_extras – Dict of scalar per-instance attributes (one value or length-1 array).

Raises:

ValueError – On shape/type/index validation errors, or on mixing externalized/materialized modes.

bounding_box_format: InitVar['xyzxyz' | 'xyzwhd'] = xyzxyz

Format of the input bounding_boxes arrays. Storage is always "xyzxyz". Applies to every instance’s bounding_boxes array uniformly. obbs is unaffected.

bounding_boxes: list[ndarray] = field(...)

List of (Bi, 6) float32 arrays. Always stored as [x_min, y_min, z_min, x_max, y_max, z_max] (xyzxyz). Use bounding_box_format= on the constructor to supply "xyzwhd" (top-corner + size) input; conversion is applied to every instance’s array.

classmethod create_empty(
*,
x_min: float | None = None,
x_max: float | None = None,
y_min: float | None = None,
y_max: float | None = None,
z_min: float | None = None,
z_max: float | None = None,
) Geometry3D

Create an empty Geometry3D container.

Parameters:
  • x_min – Minimum x coordinate (optional).

  • x_max – Maximum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • y_max – Maximum y coordinate (optional).

  • z_min – Minimum z coordinate (optional).

  • z_max – Maximum z coordinate (optional).

image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

lines: list[ndarray] = field(...)

List of line index arrays per instance

normalized: InitVar[bool] = False

Whether the input coordinates (vertices, bounding_boxes, obbs) are normalized to [0, 1].

When True, all spatial coordinates are denormalized to absolute values using the dimensions derived from bounds. Angles in obbs are not affected. Bounds must be set. Applied after bounding_box_format conversion.

property num_instances: int

Return the number of geometry instances.

obbs: list[ndarray] = field(...)

List of (Oi, 9) float32 arrays, oriented boxes per instance

per_line_extras: dict[str, list[ndarray]] = field(...)

Per-line additional data

per_triangle_extras: dict[str, list[ndarray]] = field(...)

Per-triangle additional data

per_vertex_extras: dict[str, list[ndarray]] = field(...)

Per-vertex additional data

classmethod schema(
*,
per_vertex_schemas: dict[str, Schema] | None = None,
per_triangle_schemas: dict[str, Schema] | None = None,
per_line_schemas: dict[str, Schema] | None = None,
per_instance_schemas: dict[str, Schema] | None = None,
is_bulk_data: bool = False,
x_min_default: float | None = None,
y_min_default: float | None = None,
z_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
z_max_default: float | None = None,
display_name: str = '',
description: str = '',
writable: bool = True,
default_visible: bool = True,
display_importance: float = 0,
) Schema

Build the column Schema describing a 3D geometry scene.

Parameters:
  • per_vertex_schemas – Additional attributes attached to each 3D vertex.

  • per_triangle_schemas – Additional attributes attached to each triangle.

  • per_line_schemas – Additional attributes attached to each line.

  • per_instance_schemas – Additional attributes attached per instance.

  • is_bulk_data – Declares that the data is bulk data.

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • z_min_default – Default scene z_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • z_max_default – Default scene z_max bound.

  • 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.

Returns:

A column schema describing the serialized form of this class.

triangles: list[ndarray] = field(...)

List of triangle index arrays per instance

vertices: list[ndarray] = field(...)

List of flattened vertex arrays per instance

class Geometry3DBase

Bases: tlc.data_types._geometry_base.GeometryBase

Base class for 3D geometry containers.

Provides 3D bounds (x_min, y_min, z_min, x_max, y_max, z_max). All bounds are optional (float | None).

property bounds: tuple[float | None, float | None, float | None, float | None, float | None, float | None]

Return the 3D bounds as a tuple (x_min, y_min, z_min, x_max, y_max, z_max).

property bounds_depth: float | None

Depth spanned by the bounds, i.e. z_max - (z_min or 0). None if z_max is unset.

property bounds_height: float | None

Height spanned by the bounds, i.e. y_max - (y_min or 0). None if y_max is unset.

property bounds_width: float | None

Width spanned by the bounds, i.e. x_max - (x_min or 0). None if x_max is unset.

x_max: float | None = field(...)

Maximum x coordinate of the coordinate system (optional).

x_min: float | None = field(...)

Minimum x coordinate of the coordinate system (optional).

y_max: float | None = field(...)

Maximum y coordinate of the coordinate system (optional).

y_min: float | None = field(...)

Minimum y coordinate of the coordinate system (optional).

z_max: float | None = field(...)

Maximum z coordinate of the coordinate system (optional).

z_min: float | None = field(...)

Minimum z coordinate of the coordinate system (optional).

class GeometryBase

Bases: abc.ABC

Abstract base class for all geometry instance containers.

Provides shared infrastructure for:

  • Per-instance label and confidence storage (labels / confidences)

  • Open per-instance extras dict for arbitrary attributes (per_instance_extras)

  • Bounds handling (delegated to 2D/3D subclasses)

  • Serialization infrastructure (to_row pattern)

Subclasses must implement:

  • num_instances property

  • _bounds_mapping() method

confidences: ndarray | None = None

Per-instance float confidence scores, shape (num_instances,), dtype float32.

See labels for the contract; coerced to float32 in __post_init__.

classmethod from_row(
data: Any,
) typing_extensions.Self

Construct a container from a 3LC Table row.

If data is already an instance of cls, it is returned unchanged (idempotent passthrough), which makes composition with upstream code that may or may not have already deserialized safe. Otherwise delegates to the SampleType registered under _sample_type_name.

For sample types that have a per-column convention (e.g. SegmentationPolygons and its relative field), the column-driven convention is applied by tlc.Schema.from_row() — not by this classmethod. Direct callers who want a specific convention call the conversion method on the returned dataclass (e.g. to_relative()).

Parameters:

data – A row dict, or an already-constructed instance of cls.

Returns:

A container of type cls.

labels: ndarray | None = None

Per-instance integer class labels, shape (num_instances,), dtype int32.

Plain dataclass field — pass at construction (labels=[0, 1, 0]) and read back via the same attribute. Coerced to int32 ndarray once in __post_init__. Direct post-construction assignment (bounding_boxes.labels = ...) does not coerce dtype; pass a pre-converted ndarray.

abstract property num_instances: int

Return the number of instances in this container.

per_instance_extras: dict[str, Any] = field(...)

Open dict of non-canonical per-instance attributes, with leading dimension num_instances.

Keys are user-defined (e.g. "track_id", "area"). The reserved keys "label" and "confidence" are not allowed here — they live on the dedicated labels and confidences fields. Passing them via this dict raises in __post_init__.

Values are typed as Any because the contract is intentionally open: per-instance values may be scalars, sequences, ndarrays, or composite Python objects (e.g. nested dicts). On input, sequences are coerced to ndarrays; composite objects are stored as object-dtype arrays and round-trip through serialization.

When building incrementally with add_instance(), the first call establishes which extra keys are present. All subsequent calls must provide the same keys.

to_row() dict[str, Any]

Convert this container to the 3LC Table row format.

Delegates to the SampleType registered under _sample_type_name. Convention/format options travel on the dataclass itself (e.g. SegmentationPolygons(relative=True, ...)), not on this method.

Returns:

The row-form dictionary produced by the registered sample type’s to_row.

class Keypoints2D

Bases: tlc.data_types._geometry_base.Geometry2DBase

Container for 2D keypoint instances.

Serialization is handled by the keypoints_2d sample type.

Objects can be created in two ways:

  1. Direct construction: Pass all arrays at once.

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

Example:

import numpy as np

# Direct construction
N, K = 3, 17  # 3 persons, 17 COCO keypoints
kpts = Keypoints2D(
    keypoints=np.random.rand(N, K, 2).astype(np.float32) * 640,
    labels=np.zeros(N, dtype=np.int32),
    bounding_boxes=np.array([[10, 10, 100, 200]] * N, dtype=np.float32),
    keypoint_visibilities=np.ones((N, K), dtype=np.int32) * 2,
    x_max=640.0,
    y_max=480.0,
)

# Build incrementally — naming convention:
#   instance-level: `label` / `confidence` (singular, like every other class)
#   per-keypoint:   `keypoint_visibilities` / `keypoint_confidences` (mutually exclusive)
kpts = Keypoints2D.create_empty(image_width=640, image_height=480)
kpts.add_instance(
    keypoints=[[100, 150], [120, 160], [140, 170]],
    bounding_box=[90, 140, 150, 180],
    label=0,
    confidence=0.97,
    keypoint_visibilities=[2, 2, 1],
)

# COCO-style xywh bounding boxes — converted to xyxy via bounding_box_format
kpts = Keypoints2D(
    keypoints=..., bounding_boxes=coco_xywh, bounding_box_format="xywh", x_max=640, y_max=480,
)

# Serialization — convert to/from 3LC Table row format
row = kpts.to_row()
kpts = Keypoints2D.from_row(row)
add_instance(
*,
keypoints: Any,
bounding_box: Sequence[float] | ndarray | None = None,
label: int | None = None,
confidence: float | None = None,
keypoint_visibilities: Sequence[int] | ndarray | None = None,
keypoint_confidences: Sequence[float] | ndarray | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single keypoint instance to the object.

Adds one instance (e.g., one person, one object) with its keypoints, bounding box, and label. Keypoints can be provided in multiple formats and will be normalized internally.

Parameters:
  • keypoints

    Keypoint coordinates in one of these formats:

    • Flat list: [x1, y1, x2, y2, ...] or [x1, y1, v1, x2, y2, v2, ...]

    • List of pairs: [[x1, y1], [x2, y2], ...]

    • List of triplets: [[x1, y1, v1], [x2, y2, v2], ...] (visibility derived from 3rd value)

    • NumPy array of shape (K, 2) or (K, 3)

  • bounding_box – Optional bounding box in xyxy format [x_min, y_min, x_max, y_max].

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance (instance-level).

  • keypoint_visibilities – Optional per-keypoint visibility flags (0=not labeled, 1=occluded, 2=visible). Mutually exclusive with keypoint_confidences. If keypoints are provided with a 3rd column, that will be used as visibility unless explicitly overridden.

  • keypoint_confidences – Optional per-keypoint confidence scores. Mutually exclusive with keypoint_visibilities.

  • per_instance_extras – Optional dictionary of per-instance attributes (e.g., {"track_id": 42, "area": 1500}). Values should be scalars. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If keypoints are None, if both visibility and confidence are provided, or if the number of keypoints doesn’t match existing instances.

Example:

kpts = Keypoints2D.create_empty(image_width=640, image_height=480)
# Add first instance with 3 keypoints
kpts.add_instance(
    keypoints=[[100, 150], [120, 160], [140, 170]],
    bounding_box=[90, 140, 150, 180],
    label=0,
)
# Add second instance (must also have 3 keypoints)
kpts.add_instance(
    keypoints=[[200, 250, 2], [220, 260, 2], [240, 270, 1]],  # with visibility
    bounding_box=[190, 240, 250, 280],
    label=0,
)
bounding_box_format: InitVar['xyxy' | 'xywh' | 'cxywh'] = xyxy

Format of the input bounding_boxes array (when supplied). Storage is always "xyxy".

bounding_boxes: ndarray = field(...)

Optional per-instance bounding boxes, shape (num_instances, 4) after coercion. Empty (shape (0, 4)) when not provided. Always stored as [x_min, y_min, x_max, y_max] (xyxy). Use bounding_box_format= on the constructor to supply "xywh" (COCO) or "cxywh" (YOLO) input.

property bounding_boxes_xywh: ndarray

Return the instance bounding boxes in xywh format.

Converts from the internal xyxy format [x_min, y_min, x_max, y_max] to xywh format [x_min, y_min, width, height], which is commonly used by some training frameworks.

Returns:

A numpy array of shape (num_instances, 4) with bounding boxes in [x, y, width, height] format, or an empty (0, 4) array if no bounding boxes are present.

classmethod create_empty(
*,
image_width: float | None = None,
image_height: float | None = None,
x_min: float | None = None,
y_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
) Keypoints2D

Create an empty Keypoints2D object to build up incrementally.

Useful for creating keypoint data from scratch by adding instances one at a time using add_instance().

Parameters:
  • image_width – Convenience parameter, sets x_max = x_min + image_width.

  • image_height – Convenience parameter, sets y_max = y_min + image_height.

  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • x_max – Maximum x coordinate (optional, provide this OR image_width if specifying bounds).

  • y_max – Maximum y coordinate (optional, provide this OR image_height if specifying bounds).

Returns:

An empty Keypoints2D object ready for adding instances.

Raises:

ValueError – If bounds are partially specified (some but not all required).

Example:

kpts = Keypoints2D.create_empty(image_width=640, image_height=480)
kpts.add_instance(
    keypoints=[[100, 150], [120, 160]],
    bounding_box=[90, 140, 130, 170],
    label=0,
    keypoint_visibilities=[2, 2],
)
image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

keypoint_confidences: ndarray = field(...)

Per-keypoint float confidences, shape (num_instances, num_keypoints,) after coercion. Empty (size == 0) when not provided. Same input convention as keypoint_visibilities; mutually exclusive with it.

keypoint_visibilities: ndarray = field(...)

Per-keypoint integer visibilities, shape (num_instances, num_keypoints,) after coercion. Empty (size == 0) when not provided. The constructor also accepts a 1D (K,) array for the single-instance case (broadcast to (1, K) in __post_init__). Mutually exclusive with keypoint_confidences: at most one of them may be non-empty in a container.

keypoints: ndarray = field(...)

Keypoint coordinates, ndarray of shape (num_instances, num_keypoints, 2) after coercion.

The constructor accepts anything np.asarray can convert to 2D (K, 2)/(K, 3)/(N, K*2) or 3D (N, K, 2); see __post_init__ for the recognized shapes. The type hint is the post-coercion storage form so reads (.astype/.shape/etc.) typecheck cleanly. Pass list-of-list inputs by pre-wrapping with np.asarray(...) to satisfy strict type checking, or use add_instance whose kwargs accept the wider Sequence types directly.

normalized: InitVar[bool] = False

Whether the input keypoints and bounding_boxes coordinates are normalized to [0, 1].

When True, both keypoint coordinates and bounding boxes are denormalized to absolute pixel values using the image dimensions derived from bounds. Bounds must be set. Applied after bounding_box_format conversion.

property num_instances: int

Return the number of keypoint instances.

classmethod schema(
num_keypoints: int,
classes: str | Sequence[str] | Sequence[dict[str, str]] | Sequence[MapElement] | dict[float, str] | dict[int, str] | dict[float, MapElement] | dict[int, MapElement] | None = None,
*,
points: list[float] | list[list[float]] | ndarray | None = None,
point_attributes: list[str] | list[dict[str, Any]] | None = None,
lines: list[int] | list[list[int]] | ndarray | None = None,
line_attributes: list[str] | list[dict[str, Any]] | None = None,
triangles: list[int] | list[list[int]] | ndarray | None = None,
triangle_attributes: list[str] | list[dict[str, Any]] | None = None,
flip_indices: list[int] | None = None,
oks_sigmas: list[float] | None = None,
include_per_point_confidence: bool = False,
include_per_point_visibility: bool = False,
include_per_instance_confidence: bool = False,
x_min_default: float | None = None,
y_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
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 2D keypoint instances.

Parameters:
  • num_keypoints – Number of keypoints (must be > 0).

  • classes – A class map (list of names, dict of numeric keys to names or MapElements, or a single class name) for per-instance labels, or None to skip labels.

  • points – Default relative keypoint coordinates used when creating new instances. The flattened length must be num_keypoints * 2 in the order [x0, y0, ..., xN-1, yN-1].

  • point_attributes – Per-point role names, one per keypoint.

  • lines – Default connectivity as index pairs, flattened to [i0, j0, i1, j1, ...].

  • line_attributes – Per-line role names matching the number of line pairs.

  • triangles – Default triangle faces as index triples, flattened to [i0, j0, k0, ...].

  • triangle_attributes – Per-triangle role names matching the number of triangle triples.

  • flip_indices – Indices used for horizontal-flip augmentation.

  • oks_sigmas – Object Keypoint Similarity (OKS) sigmas; defaults to uniform 1/num_keypoints.

  • include_per_point_confidence – Whether to add a per-point confidence field.

  • include_per_point_visibility – Whether to add a per-point visibility channel.

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

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • 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 – Additional per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

Raises:

ValueError – If num_keypoints <= 0.

class OrientedBoundingBoxes2D

Bases: tlc.data_types._geometry_base.Geometry2DBase

Container for 2D oriented bounding boxes.

Storage: (N, 5) array with [x_center, y_center, width, height, rotation] per box. Serialization is handled by the oriented_bounding_boxes_2d sample type.

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
obbs = OrientedBoundingBoxes2D(
    obbs=np.array([[50, 50, 80, 60, 0.5], [100, 100, 40, 30, 1.0]], dtype=np.float32),
    labels=[0, 1],
    x_max=640.0,
    y_max=480.0,
)

# Build incrementally
obbs = OrientedBoundingBoxes2D.create_empty(image_width=640, image_height=480)
obbs.add_instance(
    obb=[320, 240, 100, 50, 0.785],  # center_x, center_y, width, height, rotation
    label=0,
    confidence=0.95,
)

# Serialization — convert to/from 3LC Table row format
row = obbs.to_row()
obbs = OrientedBoundingBoxes2D.from_row(row)
add_instance(
*,
obb: list[float] | tuple[float, float, float, float, float] | ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single oriented bounding box instance to the object.

Parameters:
  • obb – Oriented bounding box in the format [x_center, y_center, width, height, rotation]. Rotation should be in radians in the range [0, pi/2). Can be provided as a list, tuple, or numpy array.

  • label – Optional integer class label for this instance.

  • confidence – Optional confidence score for this instance.

  • per_instance_extras – Optional dictionary of per-instance attributes (e.g., {"track_id": 42, "area": 1500}). Values should be scalars. The first call establishes which keys are expected; subsequent calls must provide the same keys.

Raises:

ValueError – If the OBB does not have exactly 5 elements.

Example:

obbs = OrientedBoundingBoxes2D.create_empty(image_width=640, image_height=480)
obbs.add_instance(obb=[320, 240, 100, 50, 0.785], label=0, confidence=0.95)
obbs.add_instance(obb=[200, 150, 80, 60, 1.571], label=1, confidence=0.88)
classmethod create_empty(
*,
image_width: float | None = None,
image_height: float | None = None,
x_min: float | None = None,
y_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
) OrientedBoundingBoxes2D

Create an empty OrientedBoundingBoxes2D object to build up incrementally.

Useful for creating OBB data from scratch by adding instances one at a time using add_instance().

Parameters:
  • image_width – Convenience parameter, sets x_max = x_min + image_width.

  • image_height – Convenience parameter, sets y_max = y_min + image_height.

  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • x_max – Maximum x coordinate (optional, provide this OR image_width if specifying bounds).

  • y_max – Maximum y coordinate (optional, provide this OR image_height if specifying bounds).

Returns:

An empty OrientedBoundingBoxes2D object ready for adding instances.

Example:

obbs = OrientedBoundingBoxes2D.create_empty(image_width=640, image_height=480)
obbs.add_instance(
    obb=[320, 240, 100, 50, 0.785],
    label=0,
    confidence=0.95,
    per_instance_extras={"track_id": 42, "quality_score": 0.87},
)
image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

normalized: InitVar[bool] = False

Whether the input obbs spatial coordinates are normalized to [0, 1].

When True, center (cx, cy) and size (w, h) are denormalized to absolute pixel values using the image dimensions derived from bounds. Rotation is not affected. Bounds must be set.

property num_instances: int

Return the number of OBB instances.

obbs: ndarray[tuple[int, int], dtype[numpy.float32]] = field(...)

A numpy array of shape (num_instances, 5) with [x_center, y_center, width, height, rotation] per instance.

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,
x_min_default: float | None = None,
y_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
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 2D oriented bounding boxes.

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.

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • 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 – Additional per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

class OrientedBoundingBoxes3D

Bases: tlc.data_types._geometry_base.Geometry3DBase

Container for 3D oriented bounding boxes.

Storage: (N, 9) array with [cx, cy, cz, sx, sy, sz, yaw, pitch, roll] per box. Serialization is handled by the oriented_bounding_boxes_3d sample type.

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
obbs = OrientedBoundingBoxes3D(
    obbs=np.array([[0, 0, 0, 2, 3, 4, 0.1, 0.2, 0.3]], dtype=np.float32),
    labels=[1],
    x_max=10.0, y_max=20.0, z_max=5.0,
)

# Build incrementally
obbs = OrientedBoundingBoxes3D.create_empty(x_max=10, y_max=20, z_max=5)
obbs.add_instance(obb=[0, 0, 0, 2, 3, 4, 0.1, 0.2, 0.3], label=0, confidence=0.95)

# Serialization — convert to/from 3LC Table row format
row = obbs.to_row()
obbs = OrientedBoundingBoxes3D.from_row(row)
add_instance(
*,
obb: list[float] | tuple[float, float, float, float, float, float, float, float, float] | ndarray,
label: int | None = None,
confidence: float | None = None,
per_instance_extras: Mapping[str, Any] | None = None,
) None

Add a single 3D oriented bounding box instance.

Parameters:
  • obb – Oriented bounding box as [cx, cy, cz, sx, sy, sz, yaw, pitch, roll].

  • 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 OBB does not have exactly 9 elements.

classmethod create_empty(
*,
x_min: float | None = None,
y_min: float | None = None,
z_min: float | None = None,
x_max: float | None = None,
y_max: float | None = None,
z_max: float | None = None,
) OrientedBoundingBoxes3D

Create an empty OrientedBoundingBoxes3D object to build up incrementally.

Parameters:
  • x_min – Minimum x coordinate (optional).

  • y_min – Minimum y coordinate (optional).

  • z_min – Minimum z coordinate (optional).

  • x_max – Maximum x coordinate (optional).

  • y_max – Maximum y coordinate (optional).

  • z_max – Maximum z coordinate (optional).

Returns:

An empty OrientedBoundingBoxes3D object ready for adding instances.

image_height: InitVar[float | None] = None

Convenience parameter: sets y_max = (y_min or 0) + image_height.

image_width: InitVar[float | None] = None

Convenience parameter: sets x_max = (x_min or 0) + image_width.

normalized: InitVar[bool] = False

Whether the input obbs spatial coordinates are normalized to [0, 1].

When True, center (cx, cy, cz) and size (sx, sy, sz) are denormalized to absolute values using the dimensions derived from bounds. Angles are not affected. Bounds must be set.

property num_instances: int

Return the number of OBB instances.

obbs: ndarray[tuple[int, int], dtype[numpy.float32]] = field(...)

Array of shape (num_instances, 9): [cx, cy, cz, sx, sy, sz, yaw, pitch, roll].

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,
x_min_default: float | None = None,
y_min_default: float | None = None,
z_min_default: float | None = None,
x_max_default: float | None = None,
y_max_default: float | None = None,
z_max_default: float | None = None,
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 3D oriented bounding boxes.

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.

  • x_min_default – Default scene x_min bound.

  • y_min_default – Default scene y_min bound.

  • z_min_default – Default scene z_min bound.

  • x_max_default – Default scene x_max bound.

  • y_max_default – Default scene y_max bound.

  • z_max_default – Default scene z_max bound.

  • 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 – Additional per-instance schemas (advanced).

Returns:

A column schema describing the serialized form of this class.

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.

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.

legacy_bb_row_to_bounding_boxes_2d(
row: Mapping[str, Any],
schema: Schema,
) BoundingBoxes2D

Convert a legacy BB row to a BoundingBoxes2D.

This bridges old-format table data (bb_list with x0/y0/x1/y1 dicts) to the new geometry-based BoundingBoxes2D representation. Coordinate format (XYXY, XYWH, centered-XYWH) and normalization are detected from the schema’s number roles.

Parameters:
  • row – Row dict with keys "image_width", "image_height", "bb_list".

  • schema – The column-level schema (must contain a "bb_list" sub-schema whose number roles determine the coordinate format).

Returns:

A BoundingBoxes2D in absolute XYXY format with bounds set from image dimensions.