diff --git a/scripts/utils/face_tracker.py b/scripts/utils/face_tracker.py index 305c1c1..7b2a565 100755 --- a/scripts/utils/face_tracker.py +++ b/scripts/utils/face_tracker.py @@ -111,6 +111,7 @@ def match_faces( similarity_threshold: float = 0.7, distance_threshold: float = 100.0, use_embedding: bool = True, + frame_gap: int = 1, ) -> Dict[int, int]: """ Match current frame faces to previous frame faces @@ -122,6 +123,7 @@ def match_faces( similarity_threshold: Minimum embedding similarity for matching distance_threshold: Maximum bbox center distance for matching use_embedding: Whether to use embedding similarity + frame_gap: Number of frames between current and previous (1=adjacent) Returns: Dict mapping current_face_index -> previous_face_index (or -1 if new) @@ -165,14 +167,21 @@ def match_faces( score = 0.0 + # Always reject if embedding similarity is too low (different person) + if use_embedding and curr_emb and prev_emb and similarity < 0.5: + continue + if iou > iou_threshold and similarity > similarity_threshold: score = iou + similarity - elif iou > 0.5: - score = iou * 2 + elif iou > 0.5 and similarity > 0.65: + score = iou * 1.5 + similarity * 0.5 elif similarity > 0.85: score = similarity * 2 - elif distance < distance_threshold and similarity > 0.6: + elif similarity > 0.75 and distance < distance_threshold: score = similarity - distance / 1000 + # For frame gaps (tracking lost and recovered), require higher confidence + elif frame_gap > 1 and similarity > 0.8 and iou > 0.2: + score = similarity + iou if score > best_score: best_score = score @@ -220,6 +229,7 @@ def track_faces( prev_faces = [] prev_trace_ids = [] + prev_frame_num = None print(f"\nTracking faces across {len(sorted_frames)} frames...") print(f"Parameters: iou={iou_threshold}, similarity={similarity_threshold}, distance={distance_threshold}") @@ -227,6 +237,9 @@ def track_faces( for frame_num_str, frame_data in sorted_frames: frame_num = int(frame_num_str) + frame_gap = frame_num - prev_frame_num if prev_frame_num is not None else 1 + prev_frame_num = frame_num + faces = frame_data.get("faces", []) if not faces: @@ -241,6 +254,7 @@ def track_faces( similarity_threshold, distance_threshold, use_embedding, + frame_gap, ) trace_ids = []