#include #include #include #include "face/face_recog_debug.h" #include "utils/shared_state.h" #include "../plugins/ai_face_recog/ai_face_recog_node.cpp" namespace rk3588 { namespace { Detection MakeDetection(int cls_id, int track_id, float x, float y, float w, float h) { Detection det; det.cls_id = cls_id; det.track_id = track_id; det.score = 0.95f; det.bbox = Rect{x, y, w, h}; return det; } Detection MakePersonDetection(int track_id, float x, float y, float w, float h) { return MakeDetection(0, track_id, x, y, w, h); } TEST(FaceTrackAssociationTest, PicksContainingTrackedPerson) { const Rect face{50.0f, 50.0f, 20.0f, 20.0f}; const std::vector dets = { MakePersonDetection(101, 45.0f, 45.0f, 20.0f, 20.0f), MakePersonDetection(202, 40.0f, 40.0f, 40.0f, 40.0f), MakePersonDetection(303, 10.0f, 10.0f, 15.0f, 15.0f), }; EXPECT_EQ(AssociateFaceToPersonTrack(face, dets, 0), 202); } TEST(FaceTrackAssociationTest, RejectsWhenNoTrackedPersonMatches) { const Rect face{50.0f, 50.0f, 20.0f, 20.0f}; const std::vector dets = { MakePersonDetection(-1, 45.0f, 45.0f, 20.0f, 20.0f), MakePersonDetection(404, 200.0f, 200.0f, 20.0f, 20.0f), }; EXPECT_EQ(AssociateFaceToPersonTrack(face, dets, 0), -1); } TEST(FaceTrackAssociationTest, RejectsNonPersonDetections) { const Rect face{50.0f, 50.0f, 20.0f, 20.0f}; const std::vector dets = { MakeDetection(1, 909, 40.0f, 40.0f, 40.0f, 40.0f), }; EXPECT_EQ(AssociateFaceToPersonTrack(face, dets, 0), -1); } TEST(FaceTrackAssociationTest, HonorsConfiguredPersonClassId) { const Rect face{50.0f, 50.0f, 20.0f, 20.0f}; const std::vector dets = { MakeDetection(1, 808, 40.0f, 40.0f, 40.0f, 40.0f), }; EXPECT_EQ(AssociateFaceToPersonTrack(face, dets, 1), 808); } TEST(FaceTrackAssociationTest, FallsBackToSharedTrackedPersonsWhenFrameDetectionsMissing) { const std::string state_key = "face_track_assoc_test"; SharedState::Instance().ClearTargets(state_key); TargetsSnapshot snap; snap.img_w = 1920; snap.img_h = 1080; snap.model_name = "person_det"; TrackedObject obj; obj.cls_id = 0; obj.track_id = 321; obj.score = 0.0f; obj.bbox = Rect{40.0f, 40.0f, 60.0f, 80.0f}; obj.confirmed = true; snap.objects.push_back(obj); SharedState::Instance().SetTargets(state_key, std::move(snap)); const Rect face{50.0f, 50.0f, 20.0f, 20.0f}; FaceTrackAssociationDiag diag; const int track_id = AssociateFaceToPersonTrackWithFallback(face, nullptr, 0, state_key, 1000, &diag); EXPECT_EQ(track_id, 321); EXPECT_EQ(diag.source, "shared_state"); EXPECT_EQ(diag.total_dets, 1); EXPECT_EQ(diag.person_dets, 1); EXPECT_EQ(diag.tracked_person_dets, 1); EXPECT_EQ(diag.containing_tracked_person_dets, 1); EXPECT_EQ(diag.best_track_id, 321); SharedState::Instance().ClearTargets(state_key); } TEST(FaceTrackAssociationTest, DebugLineIncludesPersonTrackId) { FaceRecogItem item; item.person_track_id = 88; item.candidate_person_id = 7; item.candidate_name = "alice"; item.best_sim = 0.89f; item.second_sim = 0.74f; item.state = FaceRecogState::Known; const std::string line = BuildFaceRecogDebugSummaryLine("face_recog", 42, item); EXPECT_NE(line.find("person_track_id=88"), std::string::npos); EXPECT_NE(line.find("candidate=alice"), std::string::npos); } } // namespace } // namespace rk3588