Add face track association diagnostics

This commit is contained in:
tian 2026-04-15 17:16:39 +08:00
parent a173ea46f9
commit ce06126ecd

View File

@ -63,16 +63,32 @@ inline bool IsPersonDetection(const Detection& det, int person_class_id) {
return det.cls_id == person_class_id;
}
int AssociateFaceToPersonTrack(const Rect& face_bbox, const std::vector<Detection>& dets, int person_class_id) {
struct FaceTrackAssociationDiag {
int total_dets = 0;
int person_dets = 0;
int tracked_person_dets = 0;
int containing_tracked_person_dets = 0;
int best_track_id = -1;
float best_overlap = -1.0f;
};
int AssociateFaceToPersonTrack(const Rect& face_bbox, const std::vector<Detection>& dets, int person_class_id,
FaceTrackAssociationDiag* diag = nullptr) {
const float center_x = face_bbox.x + face_bbox.w * 0.5f;
const float center_y = face_bbox.y + face_bbox.h * 0.5f;
if (diag) *diag = FaceTrackAssociationDiag{};
if (diag) diag->total_dets = static_cast<int>(dets.size());
int best_track_id = -1;
float best_overlap = -1.0f;
for (const auto& det : dets) {
if (diag && IsPersonDetection(det, person_class_id)) ++diag->person_dets;
if (!IsPersonDetection(det, person_class_id)) continue;
if (det.track_id < 0) continue;
if (diag) ++diag->tracked_person_dets;
if (!ContainsPoint(det.bbox, center_x, center_y)) continue;
if (diag) ++diag->containing_tracked_person_dets;
const float overlap = IntersectionArea(face_bbox, det.bbox);
if (overlap > best_overlap) {
@ -81,9 +97,34 @@ int AssociateFaceToPersonTrack(const Rect& face_bbox, const std::vector<Detectio
}
}
if (diag) {
diag->best_track_id = best_track_id;
diag->best_overlap = best_overlap;
}
return best_track_id;
}
std::string BuildFaceTrackAssociationDiagLine(const std::string& node_id, uint64_t frame_id, const Rect& face_bbox,
int person_class_id, const FaceTrackAssociationDiag& diag) {
std::ostringstream oss;
oss << "[ai_face_recog] track_assoc"
<< " id=" << node_id
<< " frame=" << frame_id
<< " person_class_id=" << person_class_id
<< " face_bbox=(" << static_cast<int>(std::lround(face_bbox.x))
<< "," << static_cast<int>(std::lround(face_bbox.y))
<< "," << static_cast<int>(std::lround(face_bbox.w))
<< "," << static_cast<int>(std::lround(face_bbox.h))
<< ")"
<< " dets=" << diag.total_dets
<< " person_dets=" << diag.person_dets
<< " tracked_person_dets=" << diag.tracked_person_dets
<< " containing_tracked_person_dets=" << diag.containing_tracked_person_dets
<< " best_track_id=" << diag.best_track_id
<< " best_overlap=" << std::fixed << std::setprecision(1) << diag.best_overlap;
return oss.str();
}
struct GalleryEntry {
int person_id = -1;
std::string name;
@ -924,6 +965,7 @@ private:
for (int i = 0; i < limit; ++i) {
const FaceDetItem& face = frame->face_det->faces[static_cast<size_t>(i)];
FaceTrackAssociationDiag assoc_diag;
face_buf_.resize(static_cast<size_t>(model_w_) * static_cast<size_t>(model_h_) * 3);
if (cfg->align && face.has_landmarks && model_w_ == 112 && model_h_ == 112) {
@ -1001,7 +1043,7 @@ private:
FaceRecogItem item;
item.bbox = face.bbox;
item.person_track_id = frame->det
? AssociateFaceToPersonTrack(face.bbox, frame->det->items, cfg->person_class_id)
? AssociateFaceToPersonTrack(face.bbox, frame->det->items, cfg->person_class_id, &assoc_diag)
: -1;
item.has_landmarks = face.has_landmarks;
item.landmarks = face.landmarks;
@ -1016,6 +1058,11 @@ private:
if (cfg->emit_embedding) item.embedding = emb;
rr.items.push_back(std::move(item));
if (cfg->debug.enabled && cfg->debug.log_matches) {
LogInfo(BuildFaceTrackAssociationDiagLine(id_, frame->frame_id, face.bbox,
cfg->person_class_id, assoc_diag));
}
}
if (sync_src) frame->SyncEnd();