OrangePi3588Media/docs/design/FaceRecognition_TrackAware_Alarm_Design.md

14 KiB
Raw Permalink Blame History

人脸识别按轨迹聚合告警设计

1. 背景

当前人脸识别告警链路为:

face_det -> face_recog -> alarm.face_rules -> actions

现有链路已经具备以下能力:

  • 从 gallery 中识别已知人员
  • 基于单帧 embedding 匹配结果输出 knownuncertain
  • 生成 known_personunknown_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 字段,但当前人脸检测节点都填的是 -1
  • FaceRecogItem 只保留了 gallery 身份字段,如 best_person_id
  • 当前人脸告警投票 key 为:
    • 已知人规则使用 best_person_id
    • 陌生人规则直接使用固定值 unknown

这意味着当前人脸告警链路无法回答以下问题:

  • 两帧是否属于同一个真实人
  • 某一帧的低分结果是否属于刚刚已经识别成功的那个人
  • 某人还在画面中时,是否应该抑制重复告警

4. 设计概述

本设计在现有人体跟踪之上增加“按轨迹聚合的人脸身份确认层”。

改造后的行为如下:

  1. 人体检测继续由现有 tracker 生成 track_id
  2. 每张识别出的人脸在同帧内关联到一个人体框
  3. 将关联后的人体 track_id 写入人脸识别结果
  4. alarmperson_track_id 聚合多帧识别证据
  5. 告警层身份判定改为三态:
    • known
    • unknown
    • uncertain
  6. 只有稳定的 known 或稳定的 unknown 才允许触发告警
  7. 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 的人体框进行关联。

建议采用以下匹配顺序:

  1. 优先选择“人脸中心点落在人框内”的人体框
  2. 若存在多个候选,则选择重叠关系最合理的那个
  3. 若不存在包含关系,可选地退化到 IoU / overlap ratio 匹配
  4. 若仍无可靠匹配,则该人脸视为未关联成功

这个方案简单、稳定,也更适合当前车间摄像头场景,因为正常情况下一个人脸应当落在一个人体框内部。

5.2 结果增强

对人脸识别结果增加与人体轨迹关联后的字段。

建议给 FaceRecogItem 增加:

  • int person_track_id = -1
  • 可选预留字段:float person_match_score

这样下游插件可以直接消费“带有人体连续性信息的人脸识别结果”,而不用再次读取原始人体框做推断。

6. 身份状态模型

alarm 节点中,按 person_track_id 维护一份短生命周期的人脸身份聚合状态。

建议维护的字段包括:

  • track_id
  • first_seen_ms
  • last_seen_ms
  • last_quality_pass_ms
  • best_known_person_id
  • best_known_name
  • best_sim_peak
  • best_known_hit_count
  • quality_pass_count
  • unknown_candidate_count
  • reported_known
  • reported_unknown
  • last_report_ms

这份状态在轨迹有效期间存在,并在短暂 retention 窗口内保留,用于实现短时离场重入抑制。

7. 三态判定模型

7.1 状态定义

每个 person_track_id 在 alarm 聚合层只能处于以下三种状态之一:

  • uncertain
    • 质量不足,或证据不足
  • known
    • 已经稳定确认属于某个已知人员
  • unknown
    • 已经稳定确认无法归属到已知人员

注意:unknown 不是人脸识别模型或 ai_face_recog 节点的单帧输出。人脸识别模型输出 embedding识别节点只判断当前帧是否可作为 known 证据;无法确认已知人时统一输出 uncertainunknown 只在 alarm 层经过质量门控、持续跟踪和低已知相似度验证后形成。

7.2 为什么必须引入 uncertain

uncertain 是本方案的关键。

以下情况都应保持为 uncertain

  • 人脸太小
  • 对齐质量差
  • 运动模糊
  • 距离过远
  • 相似度波动明显
  • 当前轨迹累计证据不足

这些观察结果都不应直接触发身份类告警。

8. 质量门控

只有通过质量门控的人脸观测,才允许进入身份聚合逻辑。

建议质量条件包括:

  • 已关联到有效 person_track_id
  • 人脸面积占比达到下限
  • 人脸长宽比处于合理范围
  • 当需要对齐时,必须具备有效 landmarks
  • 可选:人脸最小像素宽高门限
  • 可选:最小人脸检测置信度

若某一帧未通过质量门控:

  • 不计入 unknown
  • 不计入 known
  • 保持该轨迹状态为 uncertain

这与当前车间场景的业务要求一致:低质量数据可以直接忽略。

9. 已知人确认策略

已知人确认必须基于“同一人体轨迹内,对同一 gallery 身份的持续命中”。

建议条件如下:

  • 当前帧通过质量门控
  • best_person_id >= 0
  • best_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_ms
  • unknown_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. 兼容性与迁移策略

该设计应以“向后兼容优先”的方式落地。

建议策略:

  1. 保留现有 face recognition 输出字段
  2. 用新增字段而不是重命名旧字段
  3. 当 track-aware aggregation 未开启时,继续支持当前旧行为
  4. 在 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. 推荐落地顺序

建议按以下顺序逐步落地:

  1. 增加 person_track_id 传递和 debug 日志
  2. 实现按轨迹的已知人确认
  3. 实现保守的按轨迹陌生人确认
  4. 加入离场重入抑制
  5. 在 RK3588 上用已知人 / 陌生人视频做回归验证

分阶段落地可以降低风险,也更方便逐步对比行为变化。

18. 预期效果

设计实现后,车间人脸识别告警行为应达到以下效果:

  • 低质量人脸观测被直接忽略
  • 已知员工通过多帧聚合而非单帧偶然命中被确认
  • 同一个已知人不会因为个别低分帧被误报为陌生人
  • 同一个人在场期间最多触发一次身份类告警
  • 人员短时离场再进入时不会重复打卡
  • 陌生人告警数量减少,但可信度明显提高

这正是当前车间部署所需要的取舍方向:降低告警频率,提高告警精度。