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