feat(demo): add export and silhouette visualization outputs

Add preprocess-only silhouette export and configurable result exporters so demo runs can be persisted for offline analysis and reproducible evaluation. Include optional parquet support and CLI visualization dumps while updating tests and tracking notes for the verified pipeline/debug workflow.
This commit is contained in:
2026-02-27 17:16:20 +08:00
parent 3496a1beb7
commit f501119d43
10 changed files with 1101 additions and 217 deletions
+56 -3
View File
@@ -206,9 +206,9 @@ class TestSelectPerson:
def _create_mock_results(
self,
boxes_xyxy: NDArray[np.float32],
masks_data: NDArray[np.float32],
track_ids: NDArray[np.int64] | None,
boxes_xyxy: NDArray[np.float32] | torch.Tensor,
masks_data: NDArray[np.float32] | torch.Tensor,
track_ids: NDArray[np.int64] | torch.Tensor | None,
) -> Any:
"""Create a mock detection results object."""
mock_boxes = MagicMock()
@@ -344,3 +344,56 @@ class TestSelectPerson:
mask, _, _ = result
# Should be 2D (extracted from expanded 3D)
assert mask.shape == (100, 100)
def test_select_person_tensor_cpu_inputs(self) -> None:
"""Tensor-backed inputs (CPU) should work correctly."""
boxes = torch.tensor([[10.0, 10.0, 50.0, 90.0]], dtype=torch.float32)
masks = torch.rand(1, 100, 100, dtype=torch.float32)
track_ids = torch.tensor([42], dtype=torch.int64)
results = self._create_mock_results(boxes, masks, track_ids)
result = select_person(results)
assert result is not None
mask, bbox, tid = result
assert mask.shape == (100, 100)
assert bbox == (10, 10, 50, 90)
assert tid == 42
@pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available")
def test_select_person_tensor_cuda_inputs(self) -> None:
"""Tensor-backed inputs (CUDA) should work correctly."""
boxes = torch.tensor([[10.0, 10.0, 50.0, 90.0]], dtype=torch.float32).cuda()
masks = torch.rand(1, 100, 100, dtype=torch.float32).cuda()
track_ids = torch.tensor([42], dtype=torch.int64).cuda()
results = self._create_mock_results(boxes, masks, track_ids)
result = select_person(results)
assert result is not None
mask, bbox, tid = result
assert mask.shape == (100, 100)
assert bbox == (10, 10, 50, 90)
assert tid == 42
def test_select_person_tensor_multi_detection(self) -> None:
"""Multiple tensor detections should select largest bbox."""
boxes = torch.tensor(
[
[0.0, 0.0, 10.0, 10.0], # area = 100
[0.0, 0.0, 30.0, 30.0], # area = 900 (largest)
[0.0, 0.0, 20.0, 20.0], # area = 400
],
dtype=torch.float32,
)
masks = torch.rand(3, 100, 100, dtype=torch.float32)
track_ids = torch.tensor([1, 2, 3], dtype=torch.int64)
results = self._create_mock_results(boxes, masks, track_ids)
result = select_person(results)
assert result is not None
_, bbox, tid = result
assert bbox == (0, 0, 30, 30) # Largest box
assert tid == 2 # Corresponding track ID