Keep suppressed face reentry from aging unknown
This commit is contained in:
parent
2df11fa072
commit
a173ea46f9
@ -366,8 +366,7 @@
|
||||
},
|
||||
"unknown": {
|
||||
"min_track_age_ms": 2000,
|
||||
"min_quality_hits": 4,
|
||||
"reentry_cooldown_ms": 300000
|
||||
"min_quality_hits": 4
|
||||
}
|
||||
},
|
||||
"face_rules": [
|
||||
|
||||
@ -36,7 +36,6 @@ struct FaceTrackAggregationConfig {
|
||||
int known_reentry_cooldown_ms = 0;
|
||||
int unknown_min_track_age_ms = 2000;
|
||||
int unknown_min_quality_hits = 4;
|
||||
int unknown_reentry_cooldown_ms = 0;
|
||||
int state_expire_ms = 5000;
|
||||
};
|
||||
|
||||
@ -97,7 +96,6 @@ FaceTrackAggregationConfig ParseFaceTrackAggregationConfig(const SimpleJson& con
|
||||
cfg.known_reentry_cooldown_ms = std::max(0, agg->ValueOr<int>("known_reentry_cooldown_ms", cfg.known_reentry_cooldown_ms));
|
||||
cfg.unknown_min_track_age_ms = std::max(0, agg->ValueOr<int>("unknown_min_track_age_ms", cfg.unknown_min_track_age_ms));
|
||||
cfg.unknown_min_quality_hits = std::max(1, agg->ValueOr<int>("unknown_min_quality_hits", cfg.unknown_min_quality_hits));
|
||||
cfg.unknown_reentry_cooldown_ms = std::max(0, agg->ValueOr<int>("unknown_reentry_cooldown_ms", cfg.unknown_reentry_cooldown_ms));
|
||||
cfg.state_expire_ms = std::max(0, agg->ValueOr<int>("state_expire_ms", cfg.state_expire_ms));
|
||||
|
||||
if (const SimpleJson* known = agg->Find("known"); known && known->IsObject()) {
|
||||
@ -108,7 +106,6 @@ FaceTrackAggregationConfig ParseFaceTrackAggregationConfig(const SimpleJson& con
|
||||
if (const SimpleJson* unknown = agg->Find("unknown"); unknown && unknown->IsObject()) {
|
||||
cfg.unknown_min_track_age_ms = std::max(0, unknown->ValueOr<int>("min_track_age_ms", cfg.unknown_min_track_age_ms));
|
||||
cfg.unknown_min_quality_hits = std::max(1, unknown->ValueOr<int>("min_quality_hits", cfg.unknown_min_quality_hits));
|
||||
cfg.unknown_reentry_cooldown_ms = std::max(0, unknown->ValueOr<int>("reentry_cooldown_ms", cfg.unknown_reentry_cooldown_ms));
|
||||
}
|
||||
|
||||
return cfg;
|
||||
@ -176,6 +173,11 @@ FaceTrackDecision UpdateFaceTrackState(
|
||||
}
|
||||
|
||||
if (state.reported_known) return decision;
|
||||
if (!state.reported_known &&
|
||||
state.best_known_person_id >= 0 &&
|
||||
state.known_reentry_suppressed_until_ms > 0) {
|
||||
return decision;
|
||||
}
|
||||
if (state.known_reentry_suppressed_until_ms > now_ms) return decision;
|
||||
if (IsKnownLeaningTrack(state, cfg)) return decision;
|
||||
|
||||
|
||||
@ -405,6 +405,35 @@ TEST(FaceTrackAlarmTest, KnownPersonReEntryTrackCanAlarmAfterCooldownExpires) {
|
||||
EXPECT_TRUE(node.face_track_states_.at(82).reported_known);
|
||||
}
|
||||
|
||||
TEST(FaceTrackAlarmTest, SuppressedKnownReentryTrackDoesNotAgeIntoUnknownAfterSuppressionWindowWobble) {
|
||||
FaceTrackAggregationConfig cfg;
|
||||
cfg.known_min_hits = 2;
|
||||
cfg.known_hit_window_ms = 5000;
|
||||
cfg.known_reentry_cooldown_ms = 5000;
|
||||
cfg.unknown_min_track_age_ms = 1000;
|
||||
cfg.unknown_min_quality_hits = 1;
|
||||
|
||||
std::unordered_map<int, uint64_t> known_identity_last_alarm_ms;
|
||||
const FaceRecogItem initial_track = MakeKnownFace(91, 5, "alice", 0.88f);
|
||||
|
||||
FaceTrackState first_track_state;
|
||||
EXPECT_FALSE(UpdateFaceTrackState(cfg, first_track_state, known_identity_last_alarm_ms, initial_track, 1000).trigger_known);
|
||||
EXPECT_TRUE(UpdateFaceTrackState(cfg, first_track_state, known_identity_last_alarm_ms, initial_track, 1500).trigger_known);
|
||||
|
||||
FaceTrackState reentry_state;
|
||||
FaceRecogItem reentry_track = initial_track;
|
||||
reentry_track.person_track_id = 92;
|
||||
|
||||
EXPECT_FALSE(UpdateFaceTrackState(cfg, reentry_state, known_identity_last_alarm_ms, reentry_track, 4000).trigger_known);
|
||||
EXPECT_FALSE(UpdateFaceTrackState(cfg, reentry_state, known_identity_last_alarm_ms, reentry_track, 4500).trigger_known);
|
||||
|
||||
FaceRecogItem wobble = MakeUnknownFace(92, 5, "alice", 0.42f);
|
||||
const FaceTrackDecision wobble_decision = UpdateFaceTrackState(
|
||||
cfg, reentry_state, known_identity_last_alarm_ms, wobble, 7000);
|
||||
EXPECT_FALSE(wobble_decision.trigger_unknown);
|
||||
EXPECT_FALSE(reentry_state.reported_unknown);
|
||||
}
|
||||
|
||||
TEST(FaceTrackAlarmTest, IgnoresLegacyDisableFlagAndStillUsesTrackAggregation) {
|
||||
AlarmNode node;
|
||||
NodeContext ctx;
|
||||
@ -445,5 +474,38 @@ TEST(FaceTrackAlarmTest, IgnoresLegacyDisableFlagAndStillUsesTrackAggregation) {
|
||||
EXPECT_EQ(node.alarm_count_, 1u);
|
||||
}
|
||||
|
||||
TEST(FaceTrackAlarmTest, ParsesTrackAggregationWithoutUnknownReentryCooldownContract) {
|
||||
AlarmNode node;
|
||||
NodeContext ctx;
|
||||
ctx.input_queue = std::make_shared<SpscQueue<FramePtr>>(4, QueueDropStrategy::DropOldest);
|
||||
|
||||
const SimpleJson config = ParseConfig(R"({
|
||||
"id": "alarm",
|
||||
"face_rules": [
|
||||
{
|
||||
"name": "unknown_face",
|
||||
"type": "unknown",
|
||||
"cooldown_ms": 0
|
||||
}
|
||||
],
|
||||
"face_track_aggregation": {
|
||||
"known": {
|
||||
"min_hits": 2,
|
||||
"hit_window_ms": 5000,
|
||||
"reentry_cooldown_ms": 60000
|
||||
},
|
||||
"unknown": {
|
||||
"min_track_age_ms": 1200,
|
||||
"min_quality_hits": 2
|
||||
}
|
||||
}
|
||||
})");
|
||||
|
||||
ASSERT_TRUE(node.Init(config, ctx));
|
||||
EXPECT_EQ(node.track_agg_cfg_.known_reentry_cooldown_ms, 60000);
|
||||
EXPECT_EQ(node.track_agg_cfg_.unknown_min_track_age_ms, 1200);
|
||||
EXPECT_EQ(node.track_agg_cfg_.unknown_min_quality_hits, 2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace rk3588
|
||||
|
||||
Loading…
Reference in New Issue
Block a user