Add face track association diagnostics
This commit is contained in:
parent
a173ea46f9
commit
ce06126ecd
@ -63,16 +63,32 @@ inline bool IsPersonDetection(const Detection& det, int person_class_id) {
|
|||||||
return det.cls_id == 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_x = face_bbox.x + face_bbox.w * 0.5f;
|
||||||
const float center_y = face_bbox.y + face_bbox.h * 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;
|
int best_track_id = -1;
|
||||||
float best_overlap = -1.0f;
|
float best_overlap = -1.0f;
|
||||||
for (const auto& det : dets) {
|
for (const auto& det : dets) {
|
||||||
|
if (diag && IsPersonDetection(det, person_class_id)) ++diag->person_dets;
|
||||||
if (!IsPersonDetection(det, person_class_id)) continue;
|
if (!IsPersonDetection(det, person_class_id)) continue;
|
||||||
if (det.track_id < 0) continue;
|
if (det.track_id < 0) continue;
|
||||||
|
if (diag) ++diag->tracked_person_dets;
|
||||||
if (!ContainsPoint(det.bbox, center_x, center_y)) continue;
|
if (!ContainsPoint(det.bbox, center_x, center_y)) continue;
|
||||||
|
if (diag) ++diag->containing_tracked_person_dets;
|
||||||
|
|
||||||
const float overlap = IntersectionArea(face_bbox, det.bbox);
|
const float overlap = IntersectionArea(face_bbox, det.bbox);
|
||||||
if (overlap > best_overlap) {
|
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;
|
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 {
|
struct GalleryEntry {
|
||||||
int person_id = -1;
|
int person_id = -1;
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -924,6 +965,7 @@ private:
|
|||||||
|
|
||||||
for (int i = 0; i < limit; ++i) {
|
for (int i = 0; i < limit; ++i) {
|
||||||
const FaceDetItem& face = frame->face_det->faces[static_cast<size_t>(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);
|
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) {
|
if (cfg->align && face.has_landmarks && model_w_ == 112 && model_h_ == 112) {
|
||||||
@ -1001,7 +1043,7 @@ private:
|
|||||||
FaceRecogItem item;
|
FaceRecogItem item;
|
||||||
item.bbox = face.bbox;
|
item.bbox = face.bbox;
|
||||||
item.person_track_id = frame->det
|
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;
|
: -1;
|
||||||
item.has_landmarks = face.has_landmarks;
|
item.has_landmarks = face.has_landmarks;
|
||||||
item.landmarks = face.landmarks;
|
item.landmarks = face.landmarks;
|
||||||
@ -1016,6 +1058,11 @@ private:
|
|||||||
|
|
||||||
if (cfg->emit_embedding) item.embedding = emb;
|
if (cfg->emit_embedding) item.embedding = emb;
|
||||||
rr.items.push_back(std::move(item));
|
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();
|
if (sync_src) frame->SyncEnd();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user