fix(demo): clear stale classification overlay after tracking loss
This commit is contained in:
@@ -438,18 +438,22 @@ class ScoliosisPipeline:
|
||||
copy_method = cast(
|
||||
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()
|
||||
else:
|
||||
cached[k] = v
|
||||
self._last_viz_payload = cached
|
||||
|
||||
# Use cached payload if current is None
|
||||
viz_data = (
|
||||
viz_payload
|
||||
if viz_payload is not None
|
||||
else self._last_viz_payload
|
||||
)
|
||||
if viz_payload is not None:
|
||||
viz_data = viz_payload
|
||||
elif self._last_viz_payload is not None:
|
||||
viz_data = dict(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:
|
||||
# Cast viz_payload to dict for type checking
|
||||
|
||||
@@ -790,12 +790,7 @@ def test_pipeline_visualizer_updates_on_no_detection() -> None:
|
||||
assert call["confidence"] is None # No confidence when no detection
|
||||
|
||||
|
||||
def test_pipeline_visualizer_uses_cached_detection_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.
|
||||
"""
|
||||
def test_pipeline_visualizer_clears_bbox_on_no_detection() -> None:
|
||||
from opengait.demo.pipeline import ScoliosisPipeline
|
||||
|
||||
# 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[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, (
|
||||
"Frame 2 (no detection) should display cached mask from last valid detection, "
|
||||
"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[2] 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[1] == dummy_bbox_mask
|
||||
assert bbox_mask_calls[2] == dummy_bbox_mask
|
||||
assert bbox_mask_calls[3] == dummy_bbox_mask
|
||||
assert bbox_mask_calls[2] is None
|
||||
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:
|
||||
assert mask_raw_calls[1] is not mask_raw_calls[2], (
|
||||
|
||||
Reference in New Issue
Block a user