Skip to content

COCOObjectDetectionResults

SUMMARY

A batch of COCO-style object detection or instance segmentation results.

python
from telekinesis import datatypes
results = datatypes.COCOObjectDetectionResults(
    image_ids=[7, 7],
    category_ids=[1, 2],
    image_heights=[720, 720],
    image_widths=[1280, 1280],
    scores=[0.95, 0.82],
    bboxes=[[0, 0, 10, 10], [20, 20, 5, 5]],
)
API Reference
Complete API documentation for COCOObjectDetectionResults, including parameters, attributes, and methods.
View Reference →

Parameters

ParameterTypeDefaultDescription
image_idsnp.ndarray | list[int]RequiredSource image identifiers with shape (N,).
category_idsnp.ndarray | list[int]RequiredDetected category identifiers with shape (N,).
image_heightsnp.ndarray | list[int]RequiredSource image heights in pixels with shape (N,). Each value must be positive.
image_widthsnp.ndarray | list[int]RequiredSource image widths in pixels with shape (N,). Each value must be positive.
scoresnp.ndarray | list[float]RequiredDetection confidence scores with shape (N,). Each value must be greater than or equal to 0.
bboxesnp.ndarray | list[list[float]] | NoneNoneOptional bounding boxes with shape (N, 4), with one [x, y, width, height] row per result. Width and height must be non-negative. At least one of bboxes or segmentations must be provided.
segmentationslist[COCORLESegmentationLike | None] | NoneNoneOptional length-N sequence of compressed or uncompressed COCO RLE segmentations, or None entries. Provided segmentations are normalized to compressed RLE. At least one of bboxes or segmentations must be provided.

Raises

ExceptionCondition
ValueErrorBoth bboxes and segmentations are None.
ValueErrorbboxes isn't shape (N, 4), contains a non-finite value, or has negative width/height for a row.
ValueErrorAny of image_ids/category_ids/image_heights/image_widths/scores/segmentations doesn't have length N (N = len(image_ids)).
ValueErrorimage_heights/image_widths contains a value <= 0.
ValueErrorscores contains a negative or non-finite value.
TypeErrorAn entry in segmentations isn't None and isn't a dict with size/counts keys.
ValueErrorAn entry in segmentations is structurally invalid, or its size doesn't match that row's (image_height, image_width).

Attributes

AttributeTypeDescription
image_idsnp.ndarrayDefensive copy, shape (N,) int32, source image ids.
category_idsnp.ndarrayDefensive copy, shape (N,) int32, category ids.
image_heightsnp.ndarrayDefensive copy, shape (N,) int32, source image heights.
image_widthsnp.ndarrayDefensive copy, shape (N,) int32, source image widths.
scoresnp.ndarrayDefensive copy, shape (N,) float32, detection scores. Always a real array (including an empty (0,) array for an N=0 batch), never None.
bboxesnp.ndarray | NoneDefensive copy, shape (N, 4) float32, [x, y, w, h], or None if no boxes were provided.
segmentationslist[COCORLESegmentation | None] | NoneDefensive copy: a canonical encoded COCO RLE dict or None per entry, or None if no segmentations were provided.

Methods

MethodTypeDescription
COCOObjectDetectionResults.coerce(value)COCOObjectDetectionResultsConverts a dict or an existing COCOObjectDetectionResults into one. If value is already a COCOObjectDetectionResults, it is returned unchanged; a dict is unpacked into the constructor as keyword arguments.
COCOObjectDetectionResults.from_masks(*, image_ids, category_ids, scores, masks, bboxes=None)COCOObjectDetectionResultsBuilds a batch directly from a list of binary masks instead of hand-building segmentations; each mask's shape fills in that row's image_heights/image_widths automatically. Every entry in masks must be a real mask, not None.
COCOObjectDetectionResults.from_polygons(*, image_ids, category_ids, image_heights, image_widths, scores, polygons, bboxes=None)COCOObjectDetectionResultsBuilds a batch from a list of polygon segmentations (or None per entry), rasterizing each one to RLE for storage.
as_masks()COCOObjectDetectionResultsAsMasksReturns this batch with every segmentation expressed as a binary mask instead of RLE. See the linked type for the returned fields.
as_polygons(min_points=3, epsilon=0.0)COCOObjectDetectionResultsAsPolygonsReturns this batch with every segmentation expressed as polygon contours instead of RLE. min_points drops any extracted polygon with fewer vertices; epsilon, if positive, simplifies each contour by that tolerance. See the linked type for the returned fields.
COCOObjectDetectionResults.mask_to_rle(mask)COCORLESegmentationEncodes a binary mask into the canonical RLE format used for storage.
COCOObjectDetectionResults.polygon_to_rle(polygon, *, height, width)COCORLESegmentationRasterizes one or more polygons (COCOPolygonSegmentationLike) onto a canvas of the given height and width, then encodes the result as canonical RLE.
COCOObjectDetectionResults.rle_to_mask(rle)np.ndarrayDecodes an RLE segmentation (COCORLESegmentationLike) back into a binary mask, shape (H, W) and dtype uint8.
COCOObjectDetectionResults.rle_to_polygon(rle, *, min_points=3, epsilon=0.0)COCOPolygonSegmentationApproximates an RLE segmentation (COCORLESegmentationLike) as a polygon by tracing its contours via marching squares.

Operators

OperationBehavior
len(results)Number of results N in the batch.
results[i]An int returns a single COCOObjectDetectionResult. A slice or boolean np.ndarray mask returns a new COCOObjectDetectionResults sub-batch. Raises IndexError for an out-of-range int, ValueError for a boolean mask of the wrong length, TypeError for any other index type.
a == bTrue only if b is also a COCOObjectDetectionResults with equal image_ids, category_ids, bboxes, image_heights, image_widths, scores, and segmentations; NotImplemented if b isn't a COCOObjectDetectionResults.

Representations

RepresentationMethodResult
Masksas_masks()COCOObjectDetectionResultsAsMasks
Polygonsas_polygons(min_points=3, epsilon=0.0)COCOObjectDetectionResultsAsPolygons

Visualization

python
import rerun as rr

# Your code block
# ....

rr.init("coco_object_detection_results_example", spawn=True)
datatypes.visualize(results, entity_path="/results", label="COCOObjectDetectionResults")

Example

python
"""Demonstrates the Telekinesis COCOObjectDetectionResults datatype."""

import time

import numpy as np
import rerun as rr
from loguru import logger

from telekinesis import datatypes

def coco_object_detection_results_example():
    """Demonstrate creation, inspection, operations, visualization, and serialization."""

    # ======================= Create ============================================
    # Segmentation is always stored canonically as encoded COCO RLE, regardless
    # of input format. `mask_to_rle` builds one from a mask here.
    image_height, image_width = 720, 1280
    mask_0 = np.zeros((image_height, image_width), dtype=np.uint8)
    mask_0[0:10, 0:10] = 1
    mask_1 = np.zeros((image_height, image_width), dtype=np.uint8)
    mask_1[20:25, 20:25] = 1
    results = datatypes.COCOObjectDetectionResults(
        image_ids=np.array([7, 7], dtype=np.int32),
        category_ids=np.array([1, 2], dtype=np.int32),
        image_heights=np.array([image_height, image_height], dtype=np.int32),
        image_widths=np.array([image_width, image_width], dtype=np.int32),
        scores=np.array([0.95, 0.82], dtype=np.float32),
        bboxes=np.array([[0, 0, 10, 10], [20, 20, 5, 5]], dtype=np.float32),
        segmentations=[
            datatypes.COCOObjectDetectionResults.mask_to_rle(mask_0),
            datatypes.COCOObjectDetectionResults.mask_to_rle(mask_1),
        ],
    )
    logger.info(f"Created COCOObjectDetectionResults: {results}")

    results_from_polygons = datatypes.COCOObjectDetectionResults.from_polygons(
        image_ids=np.array([7, 7], dtype=np.int32),
        category_ids=np.array([1, 2], dtype=np.int32),
        image_heights=np.array([image_height, image_height], dtype=np.int32),
        image_widths=np.array([image_width, image_width], dtype=np.int32),
        scores=np.array([0.95, 0.82], dtype=np.float32),
        bboxes=np.array([[0, 0, 10, 10], [20, 20, 5, 5]], dtype=np.float32),
        polygons=[
            [[0, 2, 10, 0, 10, 10, 0, 10]],
            [[22, 20, 25, 20, 25, 25, 20, 25]],
        ],
    )
    logger.info(f"COCOObjectDetectionResults created from polygons: {results_from_polygons}")

    results_from_masks = datatypes.COCOObjectDetectionResults.from_masks(
        image_ids=np.array([7, 7], dtype=np.int32),
        category_ids=np.array([1, 2], dtype=np.int32),
        scores=np.array([0.95, 0.82], dtype=np.float32),
        masks=[mask_0, mask_1],
    )
    logger.info(f"COCOObjectDetectionResults created from masks: {results_from_masks}")

    # ======================= Inspect ===========================================
    logger.info(f"Number of results in batch: {len(results)}")
    logger.info(f"image_ids={results.image_ids}")
    logger.info(f"category_ids={results.category_ids}")
    logger.info(f"image_heights={results.image_heights}")
    logger.info(f"image_widths={results.image_widths}")
    logger.info(f"scores={results.scores}")
    logger.info(f"bboxes={results.bboxes}")
    logger.info(f"segmentations={results.segmentations}")

    # ======================= Operations =========================================
    index = 0
    first_result = results[index]
    logger.info(f"COCOObjectDetectionResult at index {index}: {first_result}")

    sliced_results = results[0:1]
    logger.info(f"Sliced COCOObjectDetectionResults: {sliced_results}")

    keep_mask = np.array([True, False])
    masked_results = results[keep_mask]
    logger.info(f"Masked COCOObjectDetectionResults: {masked_results}")

    results_as_masks = results.as_masks()
    logger.info(f"Segmentations as masks: shapes={[m.shape for m in results_as_masks['segmentations']]}")

    results_as_polygons = results.as_polygons()
    logger.info(f"Segmentations as polygons: {results_as_polygons['segmentations']}")

    # Mixin helpers shared across all COCO segmentation datatypes.
    mask_from_rle = datatypes.COCOObjectDetectionResults.rle_to_mask(results.segmentations[0])
    logger.info(f"Mask 0 decoded via rle_to_mask: shape={mask_from_rle.shape}, dtype={mask_from_rle.dtype}")

    polygon_from_rle = datatypes.COCOObjectDetectionResults.rle_to_polygon(results.segmentations[0])
    logger.info(f"Polygon 0 decoded via rle_to_polygon: {polygon_from_rle}")

    rle_from_polygon = datatypes.COCOObjectDetectionResults.polygon_to_rle(
        [[0, 2, 10, 0, 10, 10, 0, 10]], height=image_height, width=image_width
    )
    logger.info(f"RLE encoded via polygon_to_rle: {rle_from_polygon}")

    # ======================= Visualize =========================================
    rr.init("coco_object_detection_results_example", spawn=True)
    datatypes.visualize(results, entity_path="/coco_object_detection_results")
    datatypes.visualize(first_result, entity_path="/coco_object_detection_results/first_result")
    datatypes.visualize(
        results_from_polygons, entity_path="/coco_object_detection_results/from_polygons"
    )
    datatypes.visualize(results_from_masks, entity_path="/coco_object_detection_results/from_masks")

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(results)
    serialization_ms = (time.perf_counter() - start) * 1000

    start = time.perf_counter()
    deserialized = datatypes.deserialize(serialized)["param_0"]
    deserialization_ms = (time.perf_counter() - start) * 1000

    logger.info(f"Deserialized COCOObjectDetectionResults: {deserialized}")
    logger.info(f"Round-trip successful: {deserialized == results}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    coco_object_detection_results_example()