diff --git a/src/main.cpp b/src/main.cpp index 6711154..13f2131 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -206,6 +206,8 @@ int main(int argc, char** argv) { auto registry = std::make_shared( reg_cfg, EvidenceDiscounter(same_person)); + matcher_fn.set_registry(registry); + FaceTrackerFunc ftracker_fn{cfg, registry, same_person}; SceneTrackerFunc tracker_fn {cfg}; ResultSinkFunc sink_fn {cfg, done}; diff --git a/src/nodes/identity_matcher_node.hpp b/src/nodes/identity_matcher_node.hpp index e72233c..0f82004 100644 --- a/src/nodes/identity_matcher_node.hpp +++ b/src/nodes/identity_matcher_node.hpp @@ -5,6 +5,7 @@ #include "gallery/gallery_store.hpp" #include "gallery/gallery_calibration.hpp" #include "gallery/track_gallery.hpp" +#include "track_registry.hpp" #include #include @@ -115,6 +116,12 @@ struct IdentityMatcherFunc { /// mean different things. See `same_person_probability`. const GalleryCalibration& calibration() const { return cal_; } + /// TRACES: AR-012, AR-025 | SR-002 + /// Where per-frame identity evidence reaches the registry. Optional: with no + /// registry attached the matcher behaves exactly as before, which keeps the + /// replay harness and the unit tests working unchanged. + void set_registry(std::shared_ptr r) { registry_ = std::move(r); } + // Runtime setter — lets a persistent pipeline be reused across a threshold sweep // without rebuilding the (expensive, gallery-resident) matcher. The gallery, // calibration and GPU sim-engine stay put; only the accept threshold changes. @@ -232,6 +239,19 @@ struct IdentityMatcherFunc { // face (annex already folded in above); the track's diversity buffer // keeps the gallery-far views and promotes them once the track is // confirmed. No-op unless --expand-gallery is set. + // TRACES: AR-012, AR-025 | SR-002 + // Every scored face is evidence, not only the accepted ones: a run of + // near-misses for one actor is itself informative, and discarding it + // would make ownership depend on a per-frame threshold the redesign + // exists to stop relying on. The registry discounts for correlation + // and decides ownership from the accumulated posterior (AR-025). + if (registry_ && best_actor >= 0 && tf.track_ids[fi] >= 0) { + const float p = cal_.valid + ? cal_.probability(best_s, log_prior_odds_) + : std::max(0.f, best_s); + registry_->observe(tf.track_ids[fi], best_actor, p, tf.embeddings[fi]); + } + track_gallery_.observe(tf.track_ids[fi], tf.embeddings[fi], best_actor, best_s, accept, tf.crops[fi]); @@ -255,4 +275,5 @@ private: std::unique_ptr sim_engine_; TrackGallery track_gallery_; + std::shared_ptr registry_; };