rpx_benchmark.data.features
Canonical datasets.Features definitions for every RPX task.
A shared schema per task means:
- Shard-generation scripts write a known column layout.
- The
row_to_sample()bridge can dispatch on task without second-guessing what columns exist. - Third-party tooling (TypeScript SDK, parquet viewers, ...) can introspect expected columns from a single source of truth.
The schemas intentionally keep the raw modalities as HF native
Image features (PIL-decoded on read) rather than as numpy blobs:
datasets streams these lazily from Parquet / Arrow, which is
orders of magnitude faster than dumping base64 arrays.
1"""Canonical `datasets.Features` definitions for every RPX task. 2 3A shared schema per task means: 4 5- Shard-generation scripts write a known column layout. 6- The :func:`row_to_sample` bridge can dispatch on task without 7 second-guessing what columns exist. 8- Third-party tooling (TypeScript SDK, parquet viewers, ...) can 9 introspect expected columns from a single source of truth. 10 11The schemas intentionally keep **the raw modalities as HF native 12``Image`` features** (PIL-decoded on read) rather than as numpy blobs: 13``datasets`` streams these lazily from Parquet / Arrow, which is 14orders of magnitude faster than dumping base64 arrays. 15""" 16 17from __future__ import annotations 18 19from typing import Any, Dict 20 21try: 22 from datasets import Features, Image, Sequence, Value 23except ImportError as e: # pragma: no cover — fail at import time 24 raise ImportError( 25 "rpx_benchmark.data.features requires the `datasets` library. " 26 "Install with: pip install 'rpx-benchmark[hf-datasets]'" 27 ) from e 28 29from ..api import TaskType 30 31# --------------------------------------------------------------------------- # 32# Shared columns 33# --------------------------------------------------------------------------- # 34 35 36# Every RPX sample carries these top-level identity columns regardless 37# of task. Grouping them here prevents drift across per-task schemas. 38def _shared_columns() -> Dict[str, Any]: 39 return { 40 "id": Value("string"), 41 "scene": Value("string"), 42 "phase": Value("string"), # "clutter" | "interaction" | "clean" 43 "difficulty": Value("string"), # "easy" | "medium" | "hard" 44 "rgb": Image(decode=True), 45 # 4×4 SE(3) camera-to-world, row-major float32. Flattened to a 46 # fixed-length Sequence because datasets' Arrow backend stores 47 # fixed-size arrays more efficiently than ragged ones. 48 "camera_pose": Sequence(Value("float32"), length=16), 49 } 50 51 52# --------------------------------------------------------------------------- # 53# Per-task Features 54# --------------------------------------------------------------------------- # 55 56 57def _depth_features() -> Features: 58 return Features( 59 { 60 **_shared_columns(), 61 # 16-bit PNG on the wire; PIL-decoded at read time so the 62 # consumer can cast to float32 meters without re-encoding. 63 "depth": Image(decode=True), 64 } 65 ) 66 67 68def _video_depth_features() -> Features: 69 """Features for Video Depth. 70 71 Each row is a clip — not a frame — so the image columns become 72 sequences. Tooling that consumes this schema must iterate the 73 sequences pairwise (rgb_seq[t] aligns with depth_seq[t]). 74 """ 75 return Features( 76 { 77 **_shared_columns(), 78 # Per-clip arrays. Each list element is the same modality 79 # in :func:`_depth_features` for one frame within the clip. 80 "rgb_seq": Sequence(Image(decode=True)), 81 "depth_seq": Sequence(Image(decode=True)), 82 # Original phase-relative indices of the frames in this 83 # clip (lets adapters that downsample report which frames 84 # they kept). int32 on the wire. 85 "frame_indices": Sequence(Value("int32")), 86 } 87 ) 88 89 90def _detection_features() -> Features: 91 return Features( 92 { 93 **_shared_columns(), 94 "boxes": Sequence(Sequence(Value("float32"), length=4)), 95 "labels": Sequence(Value("string")), 96 } 97 ) 98 99 100def _segmentation_features() -> Features: 101 return Features( 102 { 103 **_shared_columns(), 104 # Single-channel PNG where pixel values are instance IDs. 105 "mask": Image(decode=True), 106 } 107 ) 108 109 110def _tracking_features() -> Features: 111 # Tracklets are variable-length; a struct-of-sequences layout keeps 112 # the Arrow schema cheap while preserving the tracklet grouping. 113 return Features( 114 { 115 **_shared_columns(), 116 "tracks": Sequence( 117 { 118 "track_id": Value("string"), 119 "boxes": Sequence(Sequence(Value("float32"), length=4)), 120 "scores": Sequence(Value("float32")), 121 } 122 ), 123 } 124 ) 125 126 127def _relative_pose_features() -> Features: 128 return Features( 129 { 130 **_shared_columns(), 131 "rgb_b": Image(decode=True), 132 "pose_a": Sequence(Value("float32"), length=16), 133 "pose_b": Sequence(Value("float32"), length=16), 134 } 135 ) 136 137 138def _visual_grounding_features() -> Features: 139 return Features( 140 { 141 **_shared_columns(), 142 "text": Value("string"), 143 "boxes": Sequence(Sequence(Value("float32"), length=4)), 144 "labels": Sequence(Value("string")), 145 } 146 ) 147 148 149def _sparse_depth_features() -> Features: 150 return Features( 151 { 152 **_shared_columns(), 153 "coordinates": Sequence(Sequence(Value("float32"), length=2)), 154 "depths": Sequence(Value("float32")), 155 } 156 ) 157 158 159 160 161def _keypoint_features() -> Features: 162 return Features( 163 { 164 **_shared_columns(), 165 "rgb_b": Image(decode=True), 166 "points0": Sequence(Sequence(Value("float32"), length=2)), 167 "points1": Sequence(Sequence(Value("float32"), length=2)), 168 "visibility": Sequence(Value("bool")), 169 } 170 ) 171 172 173#: Dispatch table: TaskType → HF `Features` definition. 174RPX_FEATURES: Dict[TaskType, Features] = { 175 TaskType.MONOCULAR_DEPTH: _depth_features(), 176 TaskType.VIDEO_DEPTH: _video_depth_features(), 177 TaskType.OBJECT_DETECTION: _detection_features(), 178 TaskType.OPEN_VOCAB_DETECTION: _detection_features(), 179 TaskType.OBJECT_SEGMENTATION: _segmentation_features(), 180 TaskType.OBJECT_TRACKING: _tracking_features(), 181 TaskType.RELATIVE_CAMERA_POSE: _relative_pose_features(), 182 TaskType.VISUAL_GROUNDING: _visual_grounding_features(), 183 TaskType.SPARSE_DEPTH: _sparse_depth_features(), 184 TaskType.KEYPOINT_MATCHING: _keypoint_features(), 185} 186 187 188def features_for_task(task: TaskType | str) -> Features: 189 """Return the canonical :class:`datasets.Features` for ``task``. 190 191 Parameters 192 ---------- 193 task : TaskType or str 194 195 Returns 196 ------- 197 datasets.Features 198 """ 199 if isinstance(task, str): 200 task = TaskType(task) 201 return RPX_FEATURES[task]
RPX_FEATURES: Dict[rpx_benchmark.api.TaskType, datasets.features.features.Features] =
{<TaskType.MONOCULAR_DEPTH: 'monocular_depth'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'depth': Image(mode=None, decode=True)}, <TaskType.VIDEO_DEPTH: 'video_depth'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'rgb_seq': List(Image(mode=None, decode=True)), 'depth_seq': List(Image(mode=None, decode=True)), 'frame_indices': List(Value('int32'))}, <TaskType.OBJECT_DETECTION: 'object_detection'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'boxes': List(List(Value('float32'), length=4)), 'labels': List(Value('string'))}, <TaskType.OPEN_VOCAB_DETECTION: 'open_vocab_detection'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'boxes': List(List(Value('float32'), length=4)), 'labels': List(Value('string'))}, <TaskType.OBJECT_SEGMENTATION: 'object_segmentation'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'mask': Image(mode=None, decode=True)}, <TaskType.OBJECT_TRACKING: 'object_tracking'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'tracks': {'track_id': List(Value('string')), 'boxes': List(List(List(Value('float32'), length=4))), 'scores': List(List(Value('float32')))}}, <TaskType.RELATIVE_CAMERA_POSE: 'relative_camera_pose'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'rgb_b': Image(mode=None, decode=True), 'pose_a': List(Value('float32'), length=16), 'pose_b': List(Value('float32'), length=16)}, <TaskType.VISUAL_GROUNDING: 'visual_grounding'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'text': Value('string'), 'boxes': List(List(Value('float32'), length=4)), 'labels': List(Value('string'))}, <TaskType.SPARSE_DEPTH: 'sparse_depth'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'coordinates': List(List(Value('float32'), length=2)), 'depths': List(Value('float32'))}, <TaskType.KEYPOINT_MATCHING: 'keypoint_matching'>: {'id': Value('string'), 'scene': Value('string'), 'phase': Value('string'), 'difficulty': Value('string'), 'rgb': Image(mode=None, decode=True), 'camera_pose': List(Value('float32'), length=16), 'rgb_b': Image(mode=None, decode=True), 'points0': List(List(Value('float32'), length=2)), 'points1': List(List(Value('float32'), length=2)), 'visibility': List(Value('bool'))}}
def
features_for_task( task: rpx_benchmark.api.TaskType | str) -> datasets.features.features.Features:
189def features_for_task(task: TaskType | str) -> Features: 190 """Return the canonical :class:`datasets.Features` for ``task``. 191 192 Parameters 193 ---------- 194 task : TaskType or str 195 196 Returns 197 ------- 198 datasets.Features 199 """ 200 if isinstance(task, str): 201 task = TaskType(task) 202 return RPX_FEATURES[task]
Return the canonical datasets.Features for task.
Parameters
task : TaskType or str
Returns
datasets.Features