Hide internal face tracking config
This commit is contained in:
parent
cb5fe64e2c
commit
5644a5bf0b
@ -85,7 +85,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 128,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
@ -132,7 +131,6 @@
|
||||
"cpu_affinity": [5],
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "full_pipeline_1080p_workshoe",
|
||||
"track_classes": [0],
|
||||
"ignore_classes": [],
|
||||
"high_th": 0.55,
|
||||
|
||||
@ -92,7 +92,6 @@
|
||||
"emit_embedding": false,
|
||||
"max_faces": 50,
|
||||
"person_class_id": 0,
|
||||
"track_state_key": "full_pipeline_1080p_workshoe",
|
||||
"track_state_max_age_ms": 1000,
|
||||
"input_format": "rgb",
|
||||
"input_dtype": "uint8",
|
||||
@ -104,7 +103,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
},
|
||||
"debug": {
|
||||
@ -162,7 +160,6 @@
|
||||
],
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "full_pipeline_1080p_workshoe",
|
||||
"track_classes": [
|
||||
0
|
||||
],
|
||||
|
||||
@ -101,7 +101,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
},
|
||||
"debug": {
|
||||
@ -159,7 +158,6 @@
|
||||
],
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "full_pipeline_1080p_workshoe",
|
||||
"track_classes": [
|
||||
0
|
||||
],
|
||||
|
||||
@ -63,7 +63,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "${name}",
|
||||
"track_classes": [3, 6, 10],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov8"],
|
||||
@ -121,7 +120,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "${face_gallery_path}",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -73,7 +73,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
@ -84,7 +83,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "cam1_sample_full_pipeline",
|
||||
"track_classes": [0],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov5", "yolov8"],
|
||||
@ -101,7 +99,6 @@
|
||||
"type": "gate",
|
||||
"role": "filter",
|
||||
"enable": true,
|
||||
"state_key": "cam1_sample_full_pipeline",
|
||||
"class_ids": [0],
|
||||
"require_confirmed": true,
|
||||
"min_count": 2,
|
||||
|
||||
@ -103,7 +103,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "cam1_native_main",
|
||||
"track_classes": [0],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov5", "yolov8"],
|
||||
@ -231,7 +230,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -63,7 +63,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "cam_ppe11_detection",
|
||||
"track_classes": [3, 6, 10],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov8"],
|
||||
@ -121,7 +120,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -73,7 +73,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
@ -84,7 +83,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "cam1_sample_full_pipeline",
|
||||
"track_classes": [0],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov5", "yolov8"],
|
||||
|
||||
@ -84,7 +84,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "${face_gallery_path}",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
@ -95,7 +94,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "${name}",
|
||||
"track_classes": [3, 6],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov5", "yolov8"],
|
||||
|
||||
@ -84,7 +84,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "${face_gallery_path}",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
@ -95,7 +94,6 @@
|
||||
"enable": true,
|
||||
"mode": "bytetrack_lite",
|
||||
"per_class": true,
|
||||
"state_key": "${name}",
|
||||
"track_classes": [3, 6],
|
||||
"ignore_classes": [],
|
||||
"allowed_models": ["yolov5", "yolov8"],
|
||||
|
||||
@ -60,7 +60,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -67,7 +67,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -70,7 +70,6 @@
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
}
|
||||
},
|
||||
|
||||
@ -256,7 +256,6 @@ pre_rgb -> face_det -> person_det -> person_trk -> face_recog -> ...
|
||||
"emit_embedding": false,
|
||||
"max_faces": 50,
|
||||
"person_class_id": 0,
|
||||
"track_state_key": "full_pipeline_1080p_workshoe",
|
||||
"track_state_max_age_ms": 1000,
|
||||
"input_format": "rgb",
|
||||
"input_dtype": "uint8",
|
||||
@ -268,7 +267,6 @@ pre_rgb -> face_det -> person_det -> person_trk -> face_recog -> ...
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"load_on_start": true,
|
||||
"expected_dim": 512,
|
||||
"dtype": "auto"
|
||||
},
|
||||
"debug": {
|
||||
@ -290,11 +288,14 @@ pre_rgb -> face_det -> person_det -> person_trk -> face_recog -> ...
|
||||
| `threshold.accept` | 识别为已知人的最低相似度 | 当前测试用 `0.45` |
|
||||
| `threshold.margin` | top1 与 top2 的最小差值 | 当前测试用 `0.05`,用于降低相似人员误认 |
|
||||
| `gallery.path` | SQLite 人脸库路径 | `./models/face_gallery.db` |
|
||||
| `gallery.expected_dim` | embedding 维度 | `512`,需与识别模型一致 |
|
||||
| `track_state_key` | 读取人体跟踪状态的 key | 必须与 `tracker.state_key` 一致 |
|
||||
| `track_state_max_age_ms` | 可接受的跟踪状态最大年龄 | `1000` 左右 |
|
||||
| `debug.log_matches` | 打印每次人脸匹配结果 | 测试阶段开启,正式运行可关闭 |
|
||||
|
||||
说明:
|
||||
|
||||
- 人脸识别会自动读取同一 graph 内 tracker 发布的人体跟踪状态,不需要配置 shared-state key。
|
||||
- 人脸库 embedding 维度会从图库数据自动推断,不需要在配置文件中填写。
|
||||
|
||||
识别状态含义:
|
||||
|
||||
- `known`:满足 `threshold.accept` 和 `threshold.margin`,可以作为“已知人”证据。
|
||||
|
||||
@ -22,6 +22,7 @@ enum class NodeStatus {
|
||||
};
|
||||
|
||||
struct NodeContext {
|
||||
std::string graph_name;
|
||||
// For nodes with upstream input.
|
||||
std::shared_ptr<SpscQueue<FramePtr>> input_queue;
|
||||
// For nodes that produce downstream outputs (one queue per outgoing edge).
|
||||
|
||||
@ -42,6 +42,7 @@ struct TargetsSnapshot {
|
||||
};
|
||||
|
||||
RK3588_SHARED_STATE_API uint64_t NowSteadyUs();
|
||||
RK3588_SHARED_STATE_API std::string DefaultTrackedTargetsKey(const std::string& graph_name);
|
||||
|
||||
class RK3588_SHARED_STATE_API SharedState {
|
||||
public:
|
||||
|
||||
@ -677,7 +677,7 @@ struct FaceRecogConfigSnapshot {
|
||||
std::string gallery_backend = "sqlite";
|
||||
std::string gallery_path = "./models/face_gallery.db";
|
||||
bool gallery_load_on_start = true;
|
||||
int gallery_expected_dim = 512;
|
||||
int gallery_expected_dim = 0;
|
||||
std::string gallery_dtype = "auto";
|
||||
int gallery_reload_seq = 0;
|
||||
|
||||
@ -694,7 +694,6 @@ static bool BuildFaceRecogConfigSnapshot(const SimpleJson& config,
|
||||
snap->emit_embedding = config.ValueOr<bool>("emit_embedding", snap->emit_embedding);
|
||||
snap->max_faces = std::max(1, config.ValueOr<int>("max_faces", snap->max_faces));
|
||||
snap->person_class_id = config.ValueOr<int>("person_class_id", snap->person_class_id);
|
||||
snap->track_state_key = config.ValueOr<std::string>("track_state_key", snap->track_state_key);
|
||||
snap->track_state_max_age_ms =
|
||||
std::max<int64_t>(0, static_cast<int64_t>(config.ValueOr<int>("track_state_max_age_ms",
|
||||
static_cast<int>(snap->track_state_max_age_ms))));
|
||||
@ -740,7 +739,6 @@ static bool BuildFaceRecogConfigSnapshot(const SimpleJson& config,
|
||||
snap->gallery_backend = g->ValueOr<std::string>("backend", snap->gallery_backend);
|
||||
snap->gallery_path = g->ValueOr<std::string>("path", snap->gallery_path);
|
||||
snap->gallery_load_on_start = g->ValueOr<bool>("load_on_start", snap->gallery_load_on_start);
|
||||
snap->gallery_expected_dim = std::max(0, g->ValueOr<int>("expected_dim", snap->gallery_expected_dim));
|
||||
snap->gallery_dtype = g->ValueOr<std::string>("dtype", snap->gallery_dtype);
|
||||
snap->gallery_reload_seq = g->ValueOr<int>("reload_seq", snap->gallery_reload_seq);
|
||||
}
|
||||
@ -778,6 +776,8 @@ public:
|
||||
}
|
||||
std::shared_ptr<const FaceRecogConfigSnapshot> snap;
|
||||
BuildFaceRecogConfigSnapshot(config, nullptr, snap);
|
||||
std::const_pointer_cast<FaceRecogConfigSnapshot>(snap)->track_state_key =
|
||||
DefaultTrackedTargetsKey(ctx.graph_name);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
cfg_ = std::move(snap);
|
||||
@ -844,6 +844,7 @@ public:
|
||||
" thr_accept=" + std::to_string(thr_accept) +
|
||||
" thr_margin=" + std::to_string(thr_margin) +
|
||||
" infer_interval_ms=" + std::to_string(infer_interval_ms_) +
|
||||
" shared_target_key=" + (cfg ? cfg->track_state_key : std::string{}) +
|
||||
" debug=" + std::string(debug_enabled ? "true" : "false") +
|
||||
" debug_log_matches=" + std::string(debug_log_matches ? "true" : "false") +
|
||||
" debug_min_log_interval_ms=" + std::to_string(debug_interval_ms));
|
||||
@ -871,9 +872,9 @@ public:
|
||||
|
||||
bool reload = false;
|
||||
if (base && snap) {
|
||||
std::const_pointer_cast<FaceRecogConfigSnapshot>(snap)->track_state_key = base->track_state_key;
|
||||
reload = (snap->gallery_backend != base->gallery_backend ||
|
||||
snap->gallery_path != base->gallery_path ||
|
||||
snap->gallery_expected_dim != base->gallery_expected_dim ||
|
||||
snap->gallery_dtype != base->gallery_dtype ||
|
||||
snap->gallery_reload_seq != base->gallery_reload_seq);
|
||||
}
|
||||
|
||||
@ -48,7 +48,6 @@ static bool BuildConfigSnapshot(const SimpleJson& config, std::shared_ptr<const
|
||||
std::string& err) {
|
||||
auto snap = std::make_shared<ConfigSnapshot>();
|
||||
snap->id = config.ValueOr<std::string>("id", "gate");
|
||||
snap->state_key = config.ValueOr<std::string>("state_key", "");
|
||||
snap->require_confirmed = config.ValueOr<bool>("require_confirmed", true);
|
||||
snap->min_count = config.ValueOr<int>("min_count", 1);
|
||||
snap->max_age_ms = static_cast<int64_t>(config.ValueOr<int>("max_age_ms", 800));
|
||||
@ -89,6 +88,7 @@ public:
|
||||
}
|
||||
id_ = snap->id;
|
||||
ctx_ = ctx;
|
||||
std::const_pointer_cast<ConfigSnapshot>(snap)->state_key = DefaultTrackedTargetsKey(ctx.graph_name);
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(mu_);
|
||||
cfg_ = std::move(snap);
|
||||
@ -111,6 +111,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> lk(mu_);
|
||||
if (cfg_) std::const_pointer_cast<ConfigSnapshot>(snap)->state_key = cfg_->state_key;
|
||||
cfg_ = std::move(snap);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ struct ConfigSnapshot {
|
||||
std::string mode; // off | bytetrack_lite
|
||||
bool per_class = true;
|
||||
|
||||
// If set, write current tracked targets into SharedState under this key.
|
||||
// Internal graph-scoped key used to publish current tracked targets.
|
||||
std::string state_key;
|
||||
|
||||
std::set<int> track_classes; // whitelist
|
||||
@ -115,7 +115,6 @@ static bool BuildConfigSnapshot(const SimpleJson& config, std::shared_ptr<const
|
||||
snap->id = config.ValueOr<std::string>("id", "tracker");
|
||||
snap->mode = config.ValueOr<std::string>("mode", "bytetrack_lite");
|
||||
snap->per_class = config.ValueOr<bool>("per_class", true);
|
||||
snap->state_key = config.ValueOr<std::string>("state_key", "");
|
||||
|
||||
if (const SimpleJson* tc = config.Find("track_classes")) {
|
||||
if (!ParseIntSet(*tc, snap->track_classes, err)) {
|
||||
@ -269,6 +268,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
id_ = snap->id;
|
||||
std::const_pointer_cast<ConfigSnapshot>(snap)->state_key = DefaultTrackedTargetsKey(ctx.graph_name);
|
||||
|
||||
input_queue_ = ctx.input_queue;
|
||||
if (!input_queue_) {
|
||||
@ -292,7 +292,12 @@ public:
|
||||
}
|
||||
|
||||
bool Start() override {
|
||||
LogInfo("[tracker] started id=" + id_);
|
||||
std::string state_key;
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(mu_);
|
||||
state_key = cfg_ ? cfg_->state_key : std::string{};
|
||||
}
|
||||
LogInfo("[tracker] started id=" + id_ + " shared_target_key=" + state_key);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -315,6 +320,7 @@ public:
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(mu_);
|
||||
if (cfg_) {
|
||||
std::const_pointer_cast<ConfigSnapshot>(snap)->state_key = cfg_->state_key;
|
||||
should_reset = (cfg_->mode != snap->mode) || (cfg_->per_class != snap->per_class) ||
|
||||
(cfg_->track_classes != snap->track_classes) ||
|
||||
(cfg_->ignore_classes != snap->ignore_classes) ||
|
||||
|
||||
@ -501,6 +501,7 @@ bool Graph::Build(const SimpleJson& graph_cfg, PluginLoader& loader, size_t defa
|
||||
entry.role = node_val.ValueOr<std::string>("role", "");
|
||||
entry.enabled = node_val.ValueOr<bool>("enable", true);
|
||||
entry.metrics = std::make_shared<NodeMetrics>();
|
||||
entry.context.graph_name = name_;
|
||||
entry.context.infer_backend = infer_backend_;
|
||||
if (entry.type == "preprocess" || entry.type == "ai_shoe_det" || entry.type == "ai_yolo") {
|
||||
entry.context.image_processor = HwFactory::CreateImageProcessor(entry.config);
|
||||
|
||||
@ -11,6 +11,10 @@ uint64_t NowSteadyUs() {
|
||||
.count());
|
||||
}
|
||||
|
||||
std::string DefaultTrackedTargetsKey(const std::string& graph_name) {
|
||||
return "graph:" + (graph_name.empty() ? std::string("default") : graph_name) + ":tracked_targets";
|
||||
}
|
||||
|
||||
SharedState& SharedState::Instance() {
|
||||
static SharedState inst;
|
||||
return inst;
|
||||
|
||||
@ -95,6 +95,33 @@ TEST(FaceTrackAssociationTest, FallsBackToSharedTrackedPersonsWhenFrameDetection
|
||||
SharedState::Instance().ClearTargets(state_key);
|
||||
}
|
||||
|
||||
TEST(FaceTrackAssociationTest, UsesGraphDefaultSharedTargetKey) {
|
||||
EXPECT_EQ(DefaultTrackedTargetsKey("cam1_full_pipeline"),
|
||||
"graph:cam1_full_pipeline:tracked_targets");
|
||||
EXPECT_EQ(DefaultTrackedTargetsKey(""), "graph:default:tracked_targets");
|
||||
}
|
||||
|
||||
TEST(FaceTrackAssociationTest, FaceRecogConfigUsesInternalDefaultsForTrackStateAndGalleryDim) {
|
||||
const std::string cfg_text = R"({
|
||||
"id": "face_recog",
|
||||
"track_state_key": "user_should_not_control_this",
|
||||
"gallery": {
|
||||
"backend": "sqlite",
|
||||
"path": "./models/face_gallery.db",
|
||||
"expected_dim": 999
|
||||
}
|
||||
})";
|
||||
SimpleJson cfg;
|
||||
std::string err;
|
||||
ASSERT_TRUE(ParseSimpleJson(cfg_text, cfg, err)) << err;
|
||||
|
||||
std::shared_ptr<const FaceRecogConfigSnapshot> snap;
|
||||
ASSERT_TRUE(BuildFaceRecogConfigSnapshot(cfg, nullptr, snap));
|
||||
|
||||
EXPECT_TRUE(snap->track_state_key.empty());
|
||||
EXPECT_EQ(snap->gallery_expected_dim, 0);
|
||||
}
|
||||
|
||||
TEST(FaceTrackAssociationTest, DebugLineIncludesPersonTrackId) {
|
||||
FaceRecogItem item;
|
||||
item.person_track_id = 88;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user