move_detect/tests/test_ghost.py

32 lines
1.4 KiB
Python

from collections import deque
from edge.models import Keypoint, BBox
from edge.tracking import Track, TrackFrame
from edge.detectors.ghost import GhostIncidentDetector, GhostConfig
def _track(tid, x, y, t):
fr = TrackFrame(t, BBox(x, y, x + 20, y + 60), [Keypoint(x, y, 0.9) for _ in range(17)])
return Track(tid, deque([fr], maxlen=90))
def test_lost_dangerous_track_becomes_ghost_after_wait():
d = GhostIncidentDetector(GhostConfig(reappear_s=1.0))
d.note_state(1, "FALLEN")
d.on_lost([_track(1, 100, 100, 0.0)], now=0.0)
assert d.update([], now=0.5) == [] # 아직 대기
ghosts = d.update([], now=1.5) # 재출현 없음 > 1.0s
assert len(ghosts) == 1
assert ghosts[0]["last_state"] == "FALLEN"
assert ghosts[0]["spatial"] == (110.0, 130.0) # bbox 중심
def test_non_dangerous_lost_track_is_ignored():
d = GhostIncidentDetector(GhostConfig(reappear_s=1.0))
d.note_state(1, "STANDING")
d.on_lost([_track(1, 100, 100, 0.0)], now=0.0)
assert d.update([], now=2.0) == []
def test_reappearance_near_location_cancels_ghost():
d = GhostIncidentDetector(GhostConfig(reappear_s=1.0, reappear_dist=2.0))
d.note_state(1, "FALLEN")
d.on_lost([_track(1, 100, 100, 0.0)], now=0.0)
# 인근에 새 트랙 재출현
assert d.update([_track(2, 105, 105, 0.5)], now=0.5) == []
assert d.update([], now=2.0) == [] # 취소되어 방출 없음