rpx_benchmark.metrics.pose
Relative camera pose metric calculators.
1"""Relative camera pose metric calculators.""" 2 3from __future__ import annotations 4 5from typing import Dict 6 7from ..api import RelativePoseGroundTruth, RelativePosePrediction, TaskType 8from ..exceptions import MetricError 9from .registry import MetricCalculator, register_metric 10 11 12@register_metric(TaskType.RELATIVE_CAMERA_POSE) 13class RelativePoseError(MetricCalculator): 14 """Rotation geodesic (degrees) + translation L2 (metres). 15 16 Notes 17 ----- 18 Rotations are compared in SO(3) via the geodesic distance 19 ``arccos((trace(R_pred^T R_gt) - 1) / 2)``. Quaternion inputs (4- 20 vectors) are accepted and converted to rotation matrices. 21 Translations are compared in metres with straight L2. 22 """ 23 24 name = "relative_pose_error" 25 26 def compute( 27 self, 28 prediction: RelativePosePrediction, 29 ground_truth: RelativePoseGroundTruth, 30 ) -> Dict[str, float]: 31 if not isinstance(prediction, RelativePosePrediction): 32 raise MetricError( 33 f"RelativePoseError expected RelativePosePrediction, got " 34 f"{type(prediction).__name__}", 35 ) 36 if not isinstance(ground_truth, RelativePoseGroundTruth): 37 raise MetricError( 38 f"RelativePoseError expected RelativePoseGroundTruth, got " 39 f"{type(ground_truth).__name__}", 40 ) 41 from ..evaluators import pose_metrics 42 43 return pose_metrics( 44 prediction.rotation, 45 prediction.translation, 46 ground_truth.rotation, 47 ground_truth.translation, 48 )
13@register_metric(TaskType.RELATIVE_CAMERA_POSE) 14class RelativePoseError(MetricCalculator): 15 """Rotation geodesic (degrees) + translation L2 (metres). 16 17 Notes 18 ----- 19 Rotations are compared in SO(3) via the geodesic distance 20 ``arccos((trace(R_pred^T R_gt) - 1) / 2)``. Quaternion inputs (4- 21 vectors) are accepted and converted to rotation matrices. 22 Translations are compared in metres with straight L2. 23 """ 24 25 name = "relative_pose_error" 26 27 def compute( 28 self, 29 prediction: RelativePosePrediction, 30 ground_truth: RelativePoseGroundTruth, 31 ) -> Dict[str, float]: 32 if not isinstance(prediction, RelativePosePrediction): 33 raise MetricError( 34 f"RelativePoseError expected RelativePosePrediction, got " 35 f"{type(prediction).__name__}", 36 ) 37 if not isinstance(ground_truth, RelativePoseGroundTruth): 38 raise MetricError( 39 f"RelativePoseError expected RelativePoseGroundTruth, got " 40 f"{type(ground_truth).__name__}", 41 ) 42 from ..evaluators import pose_metrics 43 44 return pose_metrics( 45 prediction.rotation, 46 prediction.translation, 47 ground_truth.rotation, 48 ground_truth.translation, 49 )
Rotation geodesic (degrees) + translation L2 (metres).
Notes
Rotations are compared in SO(3) via the geodesic distance
arccos((trace(R_pred^T R_gt) - 1) / 2). Quaternion inputs (4-
vectors) are accepted and converted to rotation matrices.
Translations are compared in metres with straight L2.
27 def compute( 28 self, 29 prediction: RelativePosePrediction, 30 ground_truth: RelativePoseGroundTruth, 31 ) -> Dict[str, float]: 32 if not isinstance(prediction, RelativePosePrediction): 33 raise MetricError( 34 f"RelativePoseError expected RelativePosePrediction, got " 35 f"{type(prediction).__name__}", 36 ) 37 if not isinstance(ground_truth, RelativePoseGroundTruth): 38 raise MetricError( 39 f"RelativePoseError expected RelativePoseGroundTruth, got " 40 f"{type(ground_truth).__name__}", 41 ) 42 from ..evaluators import pose_metrics 43 44 return pose_metrics( 45 prediction.rotation, 46 prediction.translation, 47 ground_truth.rotation, 48 ground_truth.translation, 49 )
Return a dict of metric name → scalar for one sample.
Parameters
prediction : Any
Task-specific Prediction dataclass
(e.g. DepthPrediction). The concrete type is
whatever the calculator is designed for.
ground_truth : Any
Task-specific GroundTruth dataclass
(e.g. DepthGroundTruth).
Returns
dict[str, float] Metric values. Keys should be short snake_case names; values must be numeric so the runner can average them.
Raises
MetricError When inputs have the wrong shape/type/content.