fix(demo): clear stale classification overlay after tracking loss

This commit is contained in:
2026-03-02 16:45:20 +08:00
parent f6859cfa79
commit ab738c1615
2 changed files with 25 additions and 16 deletions
+11 -7
View File
@@ -438,18 +438,22 @@ class ScoliosisPipeline:
copy_method = cast( copy_method = cast(
Callable[[], object] | None, getattr(v, "copy", None) Callable[[], object] | None, getattr(v, "copy", None)
) )
if copy_method is not None: if copy_method is not None and callable(copy_method):
cached[k] = copy_method() cached[k] = copy_method()
else: else:
cached[k] = v cached[k] = v
self._last_viz_payload = cached self._last_viz_payload = cached
# Use cached payload if current is None if viz_payload is not None:
viz_data = ( viz_data = viz_payload
viz_payload elif self._last_viz_payload is not None:
if viz_payload is not None viz_data = dict(self._last_viz_payload)
else self._last_viz_payload viz_data["bbox"] = None
) viz_data["bbox_mask"] = None
viz_data["label"] = None
viz_data["confidence"] = None
else:
viz_data = None
if viz_data is not None: if viz_data is not None:
# Cast viz_payload to dict for type checking # Cast viz_payload to dict for type checking
+14 -9
View File
@@ -790,12 +790,7 @@ def test_pipeline_visualizer_updates_on_no_detection() -> None:
assert call["confidence"] is None # No confidence when no detection assert call["confidence"] is None # No confidence when no detection
def test_pipeline_visualizer_uses_cached_detection_on_no_detection() -> None: def test_pipeline_visualizer_clears_bbox_on_no_detection() -> None:
"""Test that visualizer reuses last valid detection when current frame has no detection.
This is a regression test for the cache-reuse behavior when person temporarily
disappears from frame. The last valid silhouette/mask should be displayed.
"""
from opengait.demo.pipeline import ScoliosisPipeline from opengait.demo.pipeline import ScoliosisPipeline
# Create a minimal pipeline with mocked dependencies # Create a minimal pipeline with mocked dependencies
@@ -884,7 +879,6 @@ def test_pipeline_visualizer_uses_cached_detection_on_no_detection() -> None:
assert mask_raw_calls[0] is not None, "Frame 0 should have valid mask" assert mask_raw_calls[0] is not None, "Frame 0 should have valid mask"
assert mask_raw_calls[1] is not None, "Frame 1 should have valid mask" assert mask_raw_calls[1] is not None, "Frame 1 should have valid mask"
# Frames 2 and 3 should reuse the cached mask from frame 1 (not None)
assert mask_raw_calls[2] is not None, ( assert mask_raw_calls[2] is not None, (
"Frame 2 (no detection) should display cached mask from last valid detection, " "Frame 2 (no detection) should display cached mask from last valid detection, "
"not None/blank" "not None/blank"
@@ -902,10 +896,21 @@ def test_pipeline_visualizer_uses_cached_detection_on_no_detection() -> None:
assert segmentation_inputs[1] is not None assert segmentation_inputs[1] is not None
assert segmentation_inputs[2] is not None assert segmentation_inputs[2] is not None
assert segmentation_inputs[3] is not None assert segmentation_inputs[3] is not None
bbox_calls = [call["bbox"] for call in mock_viz.update_calls]
assert bbox_calls[0] == dummy_bbox_frame
assert bbox_calls[1] == dummy_bbox_frame
assert bbox_calls[2] is None
assert bbox_calls[3] is None
assert bbox_mask_calls[0] == dummy_bbox_mask assert bbox_mask_calls[0] == dummy_bbox_mask
assert bbox_mask_calls[1] == dummy_bbox_mask assert bbox_mask_calls[1] == dummy_bbox_mask
assert bbox_mask_calls[2] == dummy_bbox_mask assert bbox_mask_calls[2] is None
assert bbox_mask_calls[3] == dummy_bbox_mask assert bbox_mask_calls[3] is None
label_calls = [call["label"] for call in mock_viz.update_calls]
confidence_calls = [call["confidence"] for call in mock_viz.update_calls]
assert label_calls[2] is None
assert label_calls[3] is None
assert confidence_calls[2] is None
assert confidence_calls[3] is None
if mask_raw_calls[1] is not None and mask_raw_calls[2] is not None: if mask_raw_calls[1] is not None and mask_raw_calls[2] is not None:
assert mask_raw_calls[1] is not mask_raw_calls[2], ( assert mask_raw_calls[1] is not mask_raw_calls[2], (