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:
@@ -19,6 +19,8 @@ struct FacePoint {
|
|||||||
y: f64,
|
y: f64,
|
||||||
w: f64,
|
w: f64,
|
||||||
h: f64,
|
h: f64,
|
||||||
|
confidence: f64,
|
||||||
|
point_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scroll all face points for a file from Qdrant _faces collection
|
/// 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,
|
y,
|
||||||
w,
|
w,
|
||||||
h,
|
h,
|
||||||
|
confidence: payload["confidence"].as_f64().unwrap_or(0.5),
|
||||||
|
point_id: p["id"].as_u64().map(|id| id.to_string()),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -1127,6 +1131,9 @@ async fn build_face_track_nodes_from_qdrant(
|
|||||||
sum_w: f64,
|
sum_w: f64,
|
||||||
sum_h: f64,
|
sum_h: f64,
|
||||||
frames: Vec<(i64, f64, f64, f64, f64)>, // (frame, x, y, w, h)
|
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();
|
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_w: 0.0,
|
||||||
sum_h: 0.0,
|
sum_h: 0.0,
|
||||||
frames: vec![],
|
frames: vec![],
|
||||||
|
best_frame: 0,
|
||||||
|
best_confidence: 0.0,
|
||||||
|
best_point_id: None,
|
||||||
});
|
});
|
||||||
entry.frame_count += 1;
|
entry.frame_count += 1;
|
||||||
entry.start_f = entry.start_f.min(p.frame);
|
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_w += p.w;
|
||||||
entry.sum_h += p.h;
|
entry.sum_h += p.h;
|
||||||
entry.frames.push((p.frame, p.x, p.y, p.w, 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;
|
let mut count = 0;
|
||||||
@@ -1187,6 +1203,8 @@ async fn build_face_track_nodes_from_qdrant(
|
|||||||
"frame_count": agg.frame_count,
|
"frame_count": agg.frame_count,
|
||||||
"start_frame": agg.start_f,
|
"start_frame": agg.start_f,
|
||||||
"end_frame": agg.end_f,
|
"end_frame": agg.end_f,
|
||||||
|
"key_frame": agg.best_frame,
|
||||||
|
"key_face": agg.best_point_id.as_deref().unwrap_or(""),
|
||||||
"avg_bbox": {
|
"avg_bbox": {
|
||||||
"x": (agg.sum_x / agg.frame_count as f64).round() as i64,
|
"x": (agg.sum_x / agg.frame_count as f64).round() as i64,
|
||||||
"y": (agg.sum_y / agg.frame_count as f64).round() as i64,
|
"y": (agg.sum_y / agg.frame_count as f64).round() as i64,
|
||||||
|
|||||||
Reference in New Issue
Block a user