32 lines
1.4 KiB
Python
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) == [] # 취소되어 방출 없음
|