77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
from v1.pose import Keypoint, PersonPose
|
|||
|
|
from v1.evidence import assess_pose_quality, extract_evidence
|
||
|
|
from v1.tracking import PersonTracker
|
||
|
|
|
||
|
|
|
||
|
|
def _pose(box=(20.0, 20.0, 60.0, 140.0), horizontal=False, missing_ankles=False):
|
||
|
|
points = [Keypoint(float(index), float(index), 0.9) for index in range(17)]
|
||
|
|
if horizontal:
|
||
|
|
points[5] = Keypoint(20.0, 50.0, 0.9)
|
||
|
|
points[6] = Keypoint(30.0, 50.0, 0.9)
|
||
|
|
points[11] = Keypoint(70.0, 53.0, 0.9)
|
||
|
|
points[12] = Keypoint(80.0, 53.0, 0.9)
|
||
|
|
if missing_ankles:
|
||
|
|
points[15] = Keypoint(35.0, 120.0, 0.1)
|
||
|
|
points[16] = Keypoint(45.0, 120.0, 0.1)
|
||
|
|
return PersonPose(box_xyxy=box, box_confidence=0.9, keypoints=tuple(points))
|
||
|
|
|
||
|
|
|
||
|
|
def test_tracker_keeps_id_for_nearby_person_in_next_frame():
|
||
|
|
tracker = PersonTracker(max_match_distance_ratio=0.2)
|
||
|
|
|
||
|
|
first = tracker.update([_pose()], detected_at_monotonic=1.0, frame_size=(200, 200))
|
||
|
|
second = tracker.update(
|
||
|
|
[_pose(box=(23.0, 22.0, 63.0, 142.0))],
|
||
|
|
detected_at_monotonic=1.1,
|
||
|
|
frame_size=(200, 200),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert first[0].track_id == second[0].track_id
|
||
|
|
|
||
|
|
|
||
|
|
def test_missing_ankles_rejects_pose():
|
||
|
|
quality = assess_pose_quality(_pose(missing_ankles=True), threshold=0.4)
|
||
|
|
|
||
|
|
assert quality.accepted is False
|
||
|
|
assert quality.reason == "required_joint_low_confidence"
|
||
|
|
|
||
|
|
|
||
|
|
def test_horizontal_body_is_evidence_not_event():
|
||
|
|
pose = _pose(horizontal=True)
|
||
|
|
quality = assess_pose_quality(pose, threshold=0.4)
|
||
|
|
|
||
|
|
evidence = extract_evidence(pose, quality=quality, previous=None)
|
||
|
|
|
||
|
|
assert evidence.accepted is True
|
||
|
|
assert evidence.horizontal_pose is True
|
||
|
|
assert evidence.rapid_vertical_change is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_missing_pose_cannot_create_usable_evidence():
|
||
|
|
quality = assess_pose_quality(None, threshold=0.4)
|
||
|
|
|
||
|
|
evidence = extract_evidence(None, quality=quality, previous=None)
|
||
|
|
|
||
|
|
assert quality.accepted is False
|
||
|
|
assert evidence.accepted is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_large_hip_drop_is_normalized_as_rapid_vertical_evidence():
|
||
|
|
previous_pose = _pose()
|
||
|
|
current_points = list(previous_pose.keypoints)
|
||
|
|
current_points[11] = Keypoint(11.0, 100.0, 0.9)
|
||
|
|
current_points[12] = Keypoint(12.0, 100.0, 0.9)
|
||
|
|
current_pose = PersonPose(
|
||
|
|
box_xyxy=previous_pose.box_xyxy,
|
||
|
|
box_confidence=previous_pose.box_confidence,
|
||
|
|
keypoints=tuple(current_points),
|
||
|
|
)
|
||
|
|
previous_quality = assess_pose_quality(previous_pose, threshold=0.4)
|
||
|
|
current_quality = assess_pose_quality(current_pose, threshold=0.4)
|
||
|
|
previous = extract_evidence(previous_pose, quality=previous_quality, previous=None)
|
||
|
|
|
||
|
|
evidence = extract_evidence(current_pose, quality=current_quality, previous=previous)
|
||
|
|
|
||
|
|
assert evidence.accepted is True
|
||
|
|
assert evidence.rapid_vertical_change is True
|