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)Returns the number of results.
results[i]Use an integer index for one COCOObjectDetectionResult, or a slice or boolean mask for a smaller batch.
a == bCompare with another COCOObjectDetectionResults value.

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()