Files
silver_pose/docs/04-architecture.md
T

125 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 架构设计
## 系统结构
```text
海康 RTSP 流(凭证仅在本机)
↓
RTSP 采集器 / 帧时间戳
↓
Pose 推理适配器(person box + 17 keypoints)
↓
人员跟踪器(track_id)
↓
姿态质量门控 + 倒地证据提取
↓
每人摔倒事件状态机
↓
确认事件
├── PyQt 实时画面:红框、骨架、状态
├── 本地声音与弹窗
├── 标注截图
└── JSONL 事件日志
```
V1 的同一数据流既可接 RTSP,也可回放本地录像。V2 复用同一配置、事件字段和录像集,但将 Pose 推理替换为 ONNX 适配器;不得改变事件语义。
## 模块职责
| 模块 | V1 位置 | 职责 | 不负责 |
| --- | --- | --- | --- |
| 应用入口 | `v1/app.py` | 装配配置、窗口、线程和依赖 | 推理细节、事件判定 |
| 配置 | `v1/config.py` | 解析示例和本地配置,校验非敏感字段 | 保存真实凭证 |
| 视频源 | `v1/video_source.py` | 打开、读取、重连 RTSP 或录像,附带时间戳 | Pose、报警 |
| Pose 适配器 | `v1/pose.py` | 统一返回 box、关键点、置信度 | 跟踪、摔倒业务结论 |
| 跟踪 | `v1/tracking.py` | 为连续人员输出 `track_id` | 根据姿态报警 |
| 质量与证据 | `v1/evidence.py` | 过滤低质量点,计算水平姿态、下移和持续性证据 | GUI 状态 |
| 状态机 | `v1/fall_state.py` | 管理每个 ID 的 NORMAL、SUSPECT、CONFIRMED、RECOVERING | 播放声音或存文件 |
| 报警工件 | `v1/alerts.py` | 对确认事件去重、播放声音、保存截图、写日志 | 推理或事件计算 |
| PyQt UI | `v1/gui.py` | 渲染帧、骨架、状态、设置和弹窗 | 直接读 RTSP 或写判定规则 |
| 回归工具 | `v1/tests/` 与 `v1/scripts/` | 回放录像、断言事件和延迟 | 生产 UI |
## UI 导航与配置生效生命周期
PyQt 主窗口只包含实时监控和设置两个顶部 Tab。实时监控 Tab 保持视频画面优先;设置 Tab 不能直接调用视频源、Pose 或状态机。
设置页面产生的是已校验的草稿配置。用户点击开始监控时,应用创建不可变的运行配置快照与配置版本,并将该快照传给视频源、Pose、证据和状态机。运行期间编辑设置不会修改该快照;保存后的草稿在下一次开始监控时才会成为新的运行配置。FallEvent 继续记录 config_version,使截图和 JSONL 可以追溯到实际阈值。
真实 RTSP 凭证仍只由环境变量或未跟踪本地配置提供。UI 只显示环境变量是否就绪,不能回显或记录具体值。
## 状态模型
每个 `track_id` 独立维护状态:
```text
NORMAL
└─ 高质量证据显示快速下移或倒地姿态 → SUSPECT
SUSPECT
├─ 倒地证据在配置时间窗内持续 → CONFIRMED(产生一次 FallEvent)
└─ 证据消失 → NORMAL
CONFIRMED
└─ 经配置冷却与恢复稳定站立 → RECOVERING
RECOVERING
├─ 恢复证据持续 → NORMAL
└─ 再次倒地证据 → SUSPECT
```
状态机只以秒和单调时间为准,不以固定帧数为准。这样 15 FPS、30 FPS、丢帧或录像回放速度变化不会改变 1–3 秒业务目标。
## 数据和文件
| 数据 | 位置 | 规则 |
| --- | --- | --- |
| 公共配置示例 | `v1/config.example.json` | 可提交;只含 `rtsp_url_env`,不含 URL 或密码。 |
| 本地配置 | `v1/config.local.json` | 忽略提交;可引用环境变量。 |
| V1 模型 | `v1/models/best.pt` 或受控相对路径 | 记录 SHA-256、来源与验证日期。 |
| V2 模型 | `v2/assets/best.onnx` | 从锁定 V1 权重导出,记录导出命令、输入尺寸和 SHA-256。 |
| 事件截图 | `artifacts/events/YYYYMMDD/` | 文件名含事件 ID,不含客户姓名或 RTSP 地址。 |
| 事件日志 | `artifacts/events/YYYYMMDD/events.jsonl` | 一行一个 `FallEvent`。 |
| 回归录像 | `testdata/videos/` | 只保存经同意的演示素材;外部客户视频不提交。 |
| 回归标签 | `testdata/expected_events.json` | 每段录像的期望事件、非事件和最大延迟。 |
## 关键风险与应对
| 风险 | 原因 | 应对 |
| --- | --- | --- |
| 单帧误报 | 当前 `demo/` 任一规则命中即报警 | V1 用质量门控、跟踪和时序状态机;反例录像必测。 |
| 俯视关键点不稳 | 1.6 米俯视、遮挡或远距离会影响膝踝 | 全身可见前提、ROI、质量拒绝和现场回归;必要时再采集数据。 |
| RTSP 断流 | 网络抖动或摄像头重连 | 视频源显式状态、退避重连、断流不报警。 |
| 同一事件重复报警 | CONFIRMED 状态持续多帧 | 每个事件 ID 仅执行一次报警副作用,恢复后才允许新事件。 |
| Go 行为漂移 | ONNX 预后处理与 Python 不同 | 导出后跑同一录像,比较关键点、事件数量、确认时间和截图。 |
| 模型误解 | Pose 指标被误当摔倒指标 | 文案仅说明姿态模型;事件级指标单独记录。 |
## 开发顺序
1. 冻结 `demo/`、创建 V1 配置和可验证骨架。
2. 用本地录像打通 Pose、质量门控、跟踪和状态机。
3. 加入 PyQt 实时画面、RTSP 重连、报警和截图。
4. 用正反例录像和现场流完成 V1 事件级验收。
5. 锁定模型并导出 ONNX,完成 Python/ONNX 一致性。
6. 由 Go V2 重复相同行为后,再作为客户演示部署版。
## 目标目录
```text
v1/
├── app.py
├── config.py
├── config.example.json
├── gui.py
├── video_source.py
├── pose.py
├── tracking.py
├── evidence.py
├── fall_state.py
├── alerts.py
├── models/
├── scripts/
└── tests/
v2/
├── cmd/silver-pose/
├── internal/
├── assets/
└── testdata/
```