14 KiB
人脸识别按轨迹聚合告警设计
1. 背景
当前人脸识别告警链路为:
face_det -> face_recog -> alarm.face_rules -> actions
现有链路已经具备以下能力:
- 从 gallery 中识别已知人员
- 基于单帧 embedding 匹配结果输出
known或uncertain - 生成
known_person和unknown_face告警 - 通过现有 alarm action 链路上传截图和视频片段
但当前告警行为仍然主要由单帧人脸识别结果驱动。在车间测试中,同一个已知人员可能出现:
- 近距离、高质量帧触发
known_person - 远距离、小脸、低质量帧被误当作陌生人候选并触发
unknown_face
这不符合目标场景要求。对当前车间场景来说:
- 低质量人脸数据可以直接忽略
- 告警准确率优先于告警召回率
- 告警频率需要尽量低
- 已知人员告警用于后台打卡
- 人员短暂离场再进入,不应重复触发打卡告警
仓库中已经有人体 tracker 和基于 track_id 的鞋子识别逻辑。本设计优先复用这套能力,而不是再新增一套独立的人脸 tracker。
2. 目标
2.1 功能目标
- 复用现有人体
track_id进行人脸身份聚合 - 不再把
unknown简单视为known的反面 - 对低质量人脸直接忽略,而不是强行归类为
unknown_face - 告警由“按单帧”改为“按人轨迹”
- 同一个人持续在场时不重复触发告警
- 人员短时离场再进入时不立即重复告警
2.2 非目标
- 不替换现有人体 tracker 实现
- 不新增独立的人脸 tracker
- 不修改人脸 embedding 提取和 gallery 检索逻辑
- 不把检测、识别、跟踪、告警合并到一个插件中
3. 现状分析
3.1 已有能力
plugins/tracker/tracker_node.cpp- 会给
frame->det中的人体检测框写入稳定的track_id
- 会给
plugins/logic_gate/logic_gate_node.cpp- 已经基于人体
track_id做鞋子关联与规则判断
- 已经基于人体
plugins/ai_face_det/*与plugins/ai_face_recog/ai_face_recog_node.cpp- 已经能输出人脸检测和人脸识别结果
plugins/alarm/alarm_node.cpp- 已经支持人脸规则和现有告警 action 链路
3.2 当前缺口
当前人脸链路实际上没有接入人体跟踪能力:
FaceDetItem虽然有track_id字段,但当前人脸检测节点都填的是-1FaceRecogItem只保留了 gallery 身份字段,如best_person_id- 当前人脸告警投票 key 为:
- 已知人规则使用
best_person_id - 陌生人规则直接使用固定值
unknown
- 已知人规则使用
这意味着当前人脸告警链路无法回答以下问题:
- 两帧是否属于同一个真实人
- 某一帧的低分结果是否属于刚刚已经识别成功的那个人
- 某人还在画面中时,是否应该抑制重复告警
4. 设计概述
本设计在现有人体跟踪之上增加“按轨迹聚合的人脸身份确认层”。
改造后的行为如下:
- 人体检测继续由现有 tracker 生成
track_id - 每张识别出的人脸在同帧内关联到一个人体框
- 将关联后的人体
track_id写入人脸识别结果 alarm按person_track_id聚合多帧识别证据- 告警层身份判定改为三态:
knownunknownuncertain
- 只有稳定的
known或稳定的unknown才允许触发告警 uncertain状态直接忽略,不触发身份类告警
这样可以保持当前 DAG 架构和插件边界不变:
- tracker 只负责跟踪人体
- 人脸插件只负责输出识别证据。识别节点没有
unknown分类,只输出known/uncertain - alarm 节点负责业务层面的身份确认、去重和抑制
5. 数据流设计
目标运行链路变为:
person_det -> tracker -> face_det -> face_recog(face-person association) -> alarm(track-aware face rules) -> actions
5.1 人脸与人体关联
对每一张识别出的人脸,在同一帧的 frame->det 中寻找一个已经具备有效 track_id 的人体框进行关联。
建议采用以下匹配顺序:
- 优先选择“人脸中心点落在人框内”的人体框
- 若存在多个候选,则选择重叠关系最合理的那个
- 若不存在包含关系,可选地退化到 IoU / overlap ratio 匹配
- 若仍无可靠匹配,则该人脸视为未关联成功
这个方案简单、稳定,也更适合当前车间摄像头场景,因为正常情况下一个人脸应当落在一个人体框内部。
5.2 结果增强
对人脸识别结果增加与人体轨迹关联后的字段。
建议给 FaceRecogItem 增加:
int person_track_id = -1- 可选预留字段:
float person_match_score
这样下游插件可以直接消费“带有人体连续性信息的人脸识别结果”,而不用再次读取原始人体框做推断。
6. 身份状态模型
在 alarm 节点中,按 person_track_id 维护一份短生命周期的人脸身份聚合状态。
建议维护的字段包括:
track_idfirst_seen_mslast_seen_mslast_quality_pass_msbest_known_person_idbest_known_namebest_sim_peakbest_known_hit_countquality_pass_countunknown_candidate_countreported_knownreported_unknownlast_report_ms
这份状态在轨迹有效期间存在,并在短暂 retention 窗口内保留,用于实现短时离场重入抑制。
7. 三态判定模型
7.1 状态定义
每个 person_track_id 在 alarm 聚合层只能处于以下三种状态之一:
uncertain- 质量不足,或证据不足
known- 已经稳定确认属于某个已知人员
unknown- 已经稳定确认无法归属到已知人员
注意:unknown 不是人脸识别模型或 ai_face_recog 节点的单帧输出。人脸识别模型输出 embedding,识别节点只判断当前帧是否可作为 known 证据;无法确认已知人时统一输出 uncertain。unknown 只在 alarm 层经过质量门控、持续跟踪和低已知相似度验证后形成。
7.2 为什么必须引入 uncertain
uncertain 是本方案的关键。
以下情况都应保持为 uncertain:
- 人脸太小
- 对齐质量差
- 运动模糊
- 距离过远
- 相似度波动明显
- 当前轨迹累计证据不足
这些观察结果都不应直接触发身份类告警。
8. 质量门控
只有通过质量门控的人脸观测,才允许进入身份聚合逻辑。
建议质量条件包括:
- 已关联到有效
person_track_id - 人脸面积占比达到下限
- 人脸长宽比处于合理范围
- 当需要对齐时,必须具备有效 landmarks
- 可选:人脸最小像素宽高门限
- 可选:最小人脸检测置信度
若某一帧未通过质量门控:
- 不计入
unknown - 不计入
known - 保持该轨迹状态为
uncertain
这与当前车间场景的业务要求一致:低质量数据可以直接忽略。
9. 已知人确认策略
已知人确认必须基于“同一人体轨迹内,对同一 gallery 身份的持续命中”。
建议条件如下:
- 当前帧通过质量门控
best_person_id >= 0best_sim >= known_accept(best_sim - second_sim) >= known_margin- 在
known_hit_window_ms时间窗内,同一个best_person_id至少命中known_min_hits次
可选增强:
- 若
best_sim足够高且连续稳定,可允许 peak-sim 快速确认
一旦某条轨迹稳定进入 known:
- 触发一次
known_person - 标记该轨迹
reported_known = true - 在该轨迹存活期间不再重复触发已知人告警
10. 陌生人确认策略
陌生人确认必须比已知人确认更保守。
陌生人不应被定义为:
- “这一帧不是 known”
陌生人应被定义为:
- “这个人已经被持续观察了足够长时间,且人脸质量足够,但始终无法稳定归入任何已知身份”
建议条件如下:
- 当前帧通过质量门控
- 存在有效
person_track_id - 轨迹存活时间超过
unknown_min_track_age_ms - 质量合格帧数达到
unknown_min_quality_hits - 该轨迹尚未稳定确认过已知人
- 在观察窗口内始终未满足已知人确认条件
可选附加条件:
- top1 候选身份长期不稳定
- 多帧均处于低置信或模糊匹配状态后,才允许最终确认陌生人
一旦某条轨迹稳定进入 unknown:
- 触发一次
unknown_face - 标记该轨迹
reported_unknown = true - 在该轨迹存活期间不再重复触发陌生人告警
11. 告警去重与重入抑制
11.1 轨迹内去重
在同一个活跃 person_track_id 内:
known_person最多只允许触发一次unknown_face最多只允许触发一次
11.2 离场重入抑制
当前场景中的已知人告警,本质上是打卡行为,因此:
- 同一个员工仍在画面中时,不应重复打卡
- 同一个员工短暂离开又回来时,也不应立即重复打卡
建议引入两类抑制 key:
- 已知人:按
gallery person_id做冷却 - 陌生人:按最近轨迹历史做冷却,后续可再增强为更稳定的陌生人指纹
建议增加两个可配置时间:
known_reentry_cooldown_msunknown_reentry_cooldown_ms
对于已知人,冷却时间应当相对较长,因为打卡行为本来就应当是稀疏的。
12. 配置设计
建议在 alarm 侧新增一组专门的人脸轨迹聚合配置。可以挂在 face rule 相关路径下,或作为 alarm 的一个同级子配置。
建议字段如下:
{
"face_track_aggregation": {
"enable": true,
"associate_with_person_track": true,
"require_person_track": true,
"person_match_mode": "face_center_in_person",
"person_match_min_iou": 0.05,
"quality": {
"min_face_area_ratio": 0.001,
"min_face_width": 32,
"min_face_height": 32,
"require_landmarks": true
},
"known": {
"accept": 0.45,
"margin": 0.05,
"min_hits": 3,
"hit_window_ms": 3000,
"reentry_cooldown_ms": 300000
},
"unknown": {
"min_track_age_ms": 2000,
"min_quality_hits": 4,
"reentry_cooldown_ms": 300000
}
}
}
说明:
- 具体挂载位置可再根据现有配置风格微调
- 尽量保留现有 face rule 字段,避免一次性破坏旧配置
- 迁移时应优先保证兼容性和平滑切换
13. 文件级改动建议
13.1 数据结构
修改:
include/face/face_result.h
改动内容:
- 给
FaceRecogItem增加person_track_id - 可选预留后续关联置信度等扩展字段
13.2 人脸识别节点
修改:
plugins/ai_face_recog/ai_face_recog_node.cpp
改动内容:
- 对每张识别结果做人脸与人体关联
- 将关联后的人体
track_id写入FaceRecogItem - 扩展 debug 日志,输出
person_track_id
13.3 告警节点
修改:
plugins/alarm/alarm_node.cpp
改动内容:
- 增加按轨迹聚合的人脸身份状态
- 用按
track_id的持续观察,替代当前单帧驱动的陌生人确认逻辑 - face vote key 优先使用
person_track_id - 增加已知人 / 陌生人的按轨迹去重和离场重入抑制
13.4 测试
建议新增或修改以下平台无关测试:
- 人脸与人体关联逻辑测试
- 按轨迹已知人确认测试
- 按轨迹陌生人抑制测试
- 离场重入冷却测试
14. 兼容性与迁移策略
该设计应以“向后兼容优先”的方式落地。
建议策略:
- 保留现有 face recognition 输出字段
- 用新增字段而不是重命名旧字段
- 当 track-aware aggregation 未开启时,继续支持当前旧行为
- 在 rollout 期间允许旧 face rules 与新聚合模式并存,用于对比效果
这样可以实现:
- 更安全的分阶段上线
- 便于对比新旧逻辑行为差异
- 更容易在 RK3588 上做联调和回归
15. 验证策略
15.1 本地代码级验证
本地验证只聚焦平台无关逻辑:
- 人脸与人体关联行为
- 聚合状态机状态转换
- 已知人确认窗口逻辑
- 陌生人抑制逻辑
- 离场重入冷却逻辑
- 配置解析与兼容性
15.2 RK3588 设备侧验证
最终验证必须在 RK3588 上完成:
- 已知人从远到近进入画面
- 预期:延迟但稳定触发
known_person - 预期:不出现
unknown_face误报
- 预期:延迟但稳定触发
- 已知人短暂离场并快速重入
- 预期:不重复触发打卡
- 已知人长时间离场并超过冷却后再进入
- 预期:允许再次打卡
- 真正陌生人且人脸质量足够
- 预期:经过持续观察后触发一次
unknown_face
- 预期:经过持续观察后触发一次
- 低质量陌生人
- 预期:不触发告警
- 同帧多个人体
- 预期:人脸与人体关联正确,不串轨
16. 风险与缓解
风险 1:人脸与人体关联错误
影响:
- 识别证据可能被挂到错误的人体轨迹上
缓解:
- 初版先采用简单稳定的 center-in-box 匹配
- 在 debug 模式下输出
person_track_id与关联决策 - 在 RK3588 多人场景中重点验证
风险 2:陌生人确认过于保守
影响:
- 陌生人告警触发变慢,或数量减少
缓解:
- 所有陌生人阈值均做成可配置
- 在早期 rollout 阶段宁可少报,也不要在车间场景中误报
风险 3:离场重入抑制过强
影响:
- 合法的重复打卡事件可能被压掉
缓解:
- 冷却时间全部做成可配置
- 在文档与配置说明中明确“当前业务语义是打卡型告警,而不是持续在场播报”
17. 推荐落地顺序
建议按以下顺序逐步落地:
- 增加
person_track_id传递和 debug 日志 - 实现按轨迹的已知人确认
- 实现保守的按轨迹陌生人确认
- 加入离场重入抑制
- 在 RK3588 上用已知人 / 陌生人视频做回归验证
分阶段落地可以降低风险,也更方便逐步对比行为变化。
18. 预期效果
设计实现后,车间人脸识别告警行为应达到以下效果:
- 低质量人脸观测被直接忽略
- 已知员工通过多帧聚合而非单帧偶然命中被确认
- 同一个已知人不会因为个别低分帧被误报为陌生人
- 同一个人在场期间最多触发一次身份类告警
- 人员短时离场再进入时不会重复打卡
- 陌生人告警数量减少,但可信度明显提高
这正是当前车间部署所需要的取舍方向:降低告警频率,提高告警精度。