fix: face tracker embedding threshold — reject similarity < 0.5, tighten fallback to >0.75

This commit is contained in:
Accusys
2026-05-14 00:02:39 +08:00
parent 118a386f47
commit 70a796e16c

View File

@@ -111,6 +111,7 @@ def match_faces(
similarity_threshold: float = 0.7, similarity_threshold: float = 0.7,
distance_threshold: float = 100.0, distance_threshold: float = 100.0,
use_embedding: bool = True, use_embedding: bool = True,
frame_gap: int = 1,
) -> Dict[int, int]: ) -> Dict[int, int]:
""" """
Match current frame faces to previous frame faces Match current frame faces to previous frame faces
@@ -122,6 +123,7 @@ def match_faces(
similarity_threshold: Minimum embedding similarity for matching similarity_threshold: Minimum embedding similarity for matching
distance_threshold: Maximum bbox center distance for matching distance_threshold: Maximum bbox center distance for matching
use_embedding: Whether to use embedding similarity use_embedding: Whether to use embedding similarity
frame_gap: Number of frames between current and previous (1=adjacent)
Returns: Returns:
Dict mapping current_face_index -> previous_face_index (or -1 if new) Dict mapping current_face_index -> previous_face_index (or -1 if new)
@@ -165,14 +167,21 @@ def match_faces(
score = 0.0 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: if iou > iou_threshold and similarity > similarity_threshold:
score = iou + similarity score = iou + similarity
elif iou > 0.5: elif iou > 0.5 and similarity > 0.65:
score = iou * 2 score = iou * 1.5 + similarity * 0.5
elif similarity > 0.85: elif similarity > 0.85:
score = similarity * 2 score = similarity * 2
elif distance < distance_threshold and similarity > 0.6: elif similarity > 0.75 and distance < distance_threshold:
score = similarity - distance / 1000 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: if score > best_score:
best_score = score best_score = score
@@ -220,6 +229,7 @@ def track_faces(
prev_faces = [] prev_faces = []
prev_trace_ids = [] prev_trace_ids = []
prev_frame_num = None
print(f"\nTracking faces across {len(sorted_frames)} frames...") print(f"\nTracking faces across {len(sorted_frames)} frames...")
print(f"Parameters: iou={iou_threshold}, similarity={similarity_threshold}, distance={distance_threshold}") 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: for frame_num_str, frame_data in sorted_frames:
frame_num = int(frame_num_str) 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", []) faces = frame_data.get("faces", [])
if not faces: if not faces:
@@ -241,6 +254,7 @@ def track_faces(
similarity_threshold, similarity_threshold,
distance_threshold, distance_threshold,
use_embedding, use_embedding,
frame_gap,
) )
trace_ids = [] trace_ids = []