feat(perception): restore camera-first semantic candidate
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
|
||||
from k1link.compute.e52_camera_first_restoration import (
|
||||
E52_CASE_SCHEMA,
|
||||
evaluate_camera_first_case,
|
||||
)
|
||||
|
||||
PROFILE: dict[str, Any] = {
|
||||
"target_labels": ["person", "car", "bus", "truck"],
|
||||
"label_groups": {
|
||||
"person": ["person"],
|
||||
"vehicle": ["car", "bus", "truck"],
|
||||
},
|
||||
"minimum_detector_score": 0.5,
|
||||
"maximum_bbox_image_fraction": 0.25,
|
||||
"minimum_selected_lidar_points": 4,
|
||||
"minimum_selected_lidar_coverage": 0.7,
|
||||
"minimum_original_bbox_iou": 0.25,
|
||||
}
|
||||
|
||||
|
||||
def _item(*, stratum: str, snapshot: dict[str, Any]) -> dict[str, Any]:
|
||||
return {
|
||||
"item_id": "e30-review-item-" + "a" * 64,
|
||||
"stratum": stratum,
|
||||
"evidence_binding": {"source_frame_index": 259},
|
||||
"materialization": {
|
||||
"projection_width": 800,
|
||||
"projection_height": 600,
|
||||
},
|
||||
"e29_snapshot": snapshot,
|
||||
}
|
||||
|
||||
|
||||
def _case(*, stratum: str) -> dict[str, Any]:
|
||||
return {
|
||||
"sequence": 7,
|
||||
"source_stratum": stratum,
|
||||
"prediction": {
|
||||
"presence": "occupied-environment",
|
||||
"geometry_association": "independent-occupied",
|
||||
"freshness": "current",
|
||||
},
|
||||
"reference": {
|
||||
"presence": "object-present",
|
||||
"geometry_association": "object-associated",
|
||||
"freshness": "current",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _frame(instances: list[dict[str, Any]]) -> dict[str, Any]:
|
||||
return {
|
||||
"schema_version": "missioncore.panoptic-frame/v1",
|
||||
"frame_index": 259,
|
||||
"instances": instances,
|
||||
}
|
||||
|
||||
|
||||
def test_e52_restores_camera_semantic_then_derives_lidar_range() -> None:
|
||||
pixels = np.asarray([[150.0, 225.0], [152.0, 230.0], [155.0, 235.0], [160.0, 240.0]])
|
||||
depths = np.asarray([4.0, 4.2, 4.4, 4.6])
|
||||
result = evaluate_camera_first_case(
|
||||
item=_item(
|
||||
stratum="geometry-only",
|
||||
snapshot={
|
||||
"geometry_status": "single-source-geometry",
|
||||
"nearest_range_m": 3.9,
|
||||
},
|
||||
),
|
||||
e40_case=_case(stratum="geometry-only"),
|
||||
detector_frame=_frame(
|
||||
[
|
||||
{
|
||||
"instance_id": 1,
|
||||
"label": "person",
|
||||
"score": 0.99,
|
||||
"box_xyxy": [140.0, 210.0, 220.0, 450.0],
|
||||
}
|
||||
]
|
||||
),
|
||||
projected_pixels_xy=pixels,
|
||||
projected_depth_m=depths,
|
||||
projected_selected_mask=np.ones(4, dtype=np.uint8),
|
||||
profile=PROFILE,
|
||||
)
|
||||
|
||||
assert result["schema_version"] == E52_CASE_SCHEMA
|
||||
assert result["restoration"] == {
|
||||
"state": "camera-semantic-restored-with-lidar-range",
|
||||
"semantic_owner": "camera",
|
||||
"semantic_label": "person",
|
||||
"metric_geometry_owner": "lidar",
|
||||
"range_m": 4.3,
|
||||
"runtime_publishable": False,
|
||||
"requires_shadow_acceptance": True,
|
||||
}
|
||||
|
||||
|
||||
def test_e52_rejects_pathological_full_frame_detector_box() -> None:
|
||||
pixels = np.asarray([[150.0, 225.0], [152.0, 230.0], [155.0, 235.0], [160.0, 240.0]])
|
||||
result = evaluate_camera_first_case(
|
||||
item=_item(
|
||||
stratum="geometry-only",
|
||||
snapshot={"geometry_status": "single-source-geometry"},
|
||||
),
|
||||
e40_case=_case(stratum="geometry-only"),
|
||||
detector_frame=_frame(
|
||||
[
|
||||
{
|
||||
"instance_id": 1,
|
||||
"label": "car",
|
||||
"score": 0.9,
|
||||
"box_xyxy": [0.0, 0.0, 800.0, 600.0],
|
||||
}
|
||||
]
|
||||
),
|
||||
projected_pixels_xy=pixels,
|
||||
projected_depth_m=np.asarray([4.0, 4.2, 4.4, 4.6]),
|
||||
projected_selected_mask=np.ones(4, dtype=np.uint8),
|
||||
profile=PROFILE,
|
||||
)
|
||||
|
||||
assert result["candidate_camera"]["selected"] is None
|
||||
assert result["candidate_camera"]["rejected_pathological_large_box_count"] == 1
|
||||
assert result["restoration"]["state"] == "unresolved-no-camera-semantic"
|
||||
|
||||
|
||||
def test_e52_corroborates_existing_camera_semantic_without_inventing_range() -> None:
|
||||
result = evaluate_camera_first_case(
|
||||
item=_item(
|
||||
stratum="camera-only",
|
||||
snapshot={
|
||||
"label": "bus",
|
||||
"score": 0.4,
|
||||
"bbox_xyxy": [100.0, 100.0, 200.0, 200.0],
|
||||
"geometry_status": "camera-only",
|
||||
"range_m": None,
|
||||
},
|
||||
),
|
||||
e40_case=_case(stratum="camera-only"),
|
||||
detector_frame=_frame(
|
||||
[
|
||||
{
|
||||
"instance_id": 4,
|
||||
"label": "truck",
|
||||
"score": 0.95,
|
||||
"box_xyxy": [105.0, 105.0, 205.0, 205.0],
|
||||
}
|
||||
]
|
||||
),
|
||||
projected_pixels_xy=np.empty((0, 2), dtype=np.float64),
|
||||
projected_depth_m=np.empty(0, dtype=np.float64),
|
||||
projected_selected_mask=np.empty(0, dtype=np.uint8),
|
||||
profile=PROFILE,
|
||||
)
|
||||
|
||||
assert result["restoration"]["state"] == "camera-semantic-corroborated-no-lidar-range"
|
||||
assert result["restoration"]["semantic_label"] == "truck"
|
||||
assert result["restoration"]["range_m"] is None
|
||||
Reference in New Issue
Block a user