fix: face tracker embedding threshold — reject similarity < 0.5, tighten fallback to >0.75
This commit is contained in:
@@ -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 = []
|
||||
|
||||
Reference in New Issue
Block a user