feat: auto-populate key_frame and key_face in TKG face_track nodes

- FacePoint now includes confidence and point_id from Qdrant
- TKG build tracks best face (highest confidence) per trace
- key_frame = frame number of best face, key_face = Qdrant point ID
- Every face trace now has representative frame and face for UI display
This commit is contained in:
Accusys
2026-07-21 03:56:25 +08:00
parent 644516769c
commit 6f5d71763f
+18
View File
@@ -19,6 +19,8 @@ struct FacePoint {
y: f64,
w: f64,
h: f64,
confidence: f64,
point_id: Option<String>,
}
/// Scroll all face points for a file from Qdrant _faces collection
@@ -118,6 +120,8 @@ fn parse_face_points(points: Vec<serde_json::Value>) -> Vec<FacePoint> {
y,
w,
h,
confidence: payload["confidence"].as_f64().unwrap_or(0.5),
point_id: p["id"].as_u64().map(|id| id.to_string()),
})
})
.collect();
@@ -1127,6 +1131,9 @@ async fn build_face_track_nodes_from_qdrant(
sum_w: f64,
sum_h: f64,
frames: Vec<(i64, f64, f64, f64, f64)>, // (frame, x, y, w, h)
best_frame: i64,
best_confidence: f64,
best_point_id: Option<String>,
}
let mut traces: HashMap<i64, TraceAgg> = HashMap::new();
@@ -1140,6 +1147,9 @@ async fn build_face_track_nodes_from_qdrant(
sum_w: 0.0,
sum_h: 0.0,
frames: vec![],
best_frame: 0,
best_confidence: 0.0,
best_point_id: None,
});
entry.frame_count += 1;
entry.start_f = entry.start_f.min(p.frame);
@@ -1149,6 +1159,12 @@ async fn build_face_track_nodes_from_qdrant(
entry.sum_w += p.w;
entry.sum_h += p.h;
entry.frames.push((p.frame, p.x, p.y, p.w, p.h));
// Track best face (highest confidence)
if p.confidence > entry.best_confidence {
entry.best_confidence = p.confidence;
entry.best_frame = p.frame;
entry.best_point_id = p.point_id.clone();
}
}
let mut count = 0;
@@ -1187,6 +1203,8 @@ async fn build_face_track_nodes_from_qdrant(
"frame_count": agg.frame_count,
"start_frame": agg.start_f,
"end_frame": agg.end_f,
"key_frame": agg.best_frame,
"key_face": agg.best_point_id.as_deref().unwrap_or(""),
"avg_bbox": {
"x": (agg.sum_x / agg.frame_count as f64).round() as i64,
"y": (agg.sum_y / agg.frame_count as f64).round() as i64,