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]],
)Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
image_ids | np.ndarray | list[int] | Required | Source image identifiers with shape (N,). |
category_ids | np.ndarray | list[int] | Required | Detected category identifiers with shape (N,). |
image_heights | np.ndarray | list[int] | Required | Source image heights in pixels with shape (N,). Each value must be positive. |
image_widths | np.ndarray | list[int] | Required | Source image widths in pixels with shape (N,). Each value must be positive. |
scores | np.ndarray | list[float] | Required | Detection confidence scores with shape (N,). Each value must be greater than or equal to 0. |
bboxes | np.ndarray | list[list[float]] | None | None | Optional 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. |
segmentations | list[COCORLESegmentationLike | None] | None | None | Optional 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
| Exception | Condition |
|---|---|
ValueError | Both bboxes and segmentations are None. |
ValueError | bboxes isn't shape (N, 4), contains a non-finite value, or has negative width/height for a row. |
ValueError | Any of image_ids/category_ids/image_heights/image_widths/scores/segmentations doesn't have length N (N = len(image_ids)). |
ValueError | image_heights/image_widths contains a value <= 0. |
ValueError | scores contains a negative or non-finite value. |
TypeError | An entry in segmentations isn't None and isn't a dict with size/counts keys. |
ValueError | An entry in segmentations is structurally invalid, or its size doesn't match that row's (image_height, image_width). |
Attributes
| Attribute | Type | Description |
|---|---|---|
image_ids | np.ndarray | Defensive copy, shape (N,) int32, source image ids. |
category_ids | np.ndarray | Defensive copy, shape (N,) int32, category ids. |
image_heights | np.ndarray | Defensive copy, shape (N,) int32, source image heights. |
image_widths | np.ndarray | Defensive copy, shape (N,) int32, source image widths. |
scores | np.ndarray | Defensive copy, shape (N,) float32, detection scores. Always a real array (including an empty (0,) array for an N=0 batch), never None. |
bboxes | np.ndarray | None | Defensive copy, shape (N, 4) float32, [x, y, w, h], or None if no boxes were provided. |
segmentations | list[COCORLESegmentation | None] | None | Defensive copy: a canonical encoded COCO RLE dict or None per entry, or None if no segmentations were provided. |
Methods
| Method | Type | Description |
|---|---|---|
COCOObjectDetectionResults.coerce(value) | COCOObjectDetectionResults | Converts 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) | COCOObjectDetectionResults | Builds 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) | COCOObjectDetectionResults | Builds a batch from a list of polygon segmentations (or None per entry), rasterizing each one to RLE for storage. |
as_masks() | COCOObjectDetectionResultsAsMasks | Returns 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) | COCOObjectDetectionResultsAsPolygons | Returns 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) | COCORLESegmentation | Encodes a binary mask into the canonical RLE format used for storage. |
COCOObjectDetectionResults.polygon_to_rle(polygon, *, height, width) | COCORLESegmentation | Rasterizes 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.ndarray | Decodes 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) | COCOPolygonSegmentation | Approximates an RLE segmentation (COCORLESegmentationLike) as a polygon by tracing its contours via marching squares. |
Operators
| Operation | Behavior |
|---|---|
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 == b | True 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
| Representation | Method | Result |
|---|---|---|
| Masks | as_masks() | COCOObjectDetectionResultsAsMasks |
| Polygons | as_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()
