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,
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 = []