Add reverse workspace filter option

This commit is contained in:
gqc
2026-07-08 19:16:02 +08:00
parent 041c830bfb
commit cb078492bc
6 changed files with 215 additions and 44 deletions
+119
View File
@@ -0,0 +1,119 @@
# `-R` 反向 workspace 过滤设计记录
## 背景
当前推理程序通过 `-w/--workspace` 配置一个多边形工作区域。检测结果在进入上报候选前,会用目标框中心点调用 `is_point_in_workspace(left, top, right, bottom)` 判断是否位于该区域内:
- 在 workspace 内:继续进入 `current_objects`,后续按类别编码合并并上报。
- 在 workspace 外:记录 `filtered_workspace`,不参与上报。
- 未传 `-w``init_polygon(NULL, 0)`,默认全画面有效。
本次需求是新增 `-R` 参数,让 `-w` 画出来的区域变成排除区域:开启 `-R` 后,区域内的识别结果不上报,只上报区域外的内容。
## 准备实现方式
1. 在命令行参数解析里新增无参数开关:
- 短参数:`-R`
- 长参数建议:`--reverse-workspace` 或沿用旧目录线索里的 `--reverse-detect`
- 默认关闭,保持现有行为完全不变。
2. 增加一个全局配置变量,例如:
- `bool ReverseWorkspace = false;`
- 放在 `vertix.cpp/vertix.h` 或更靠近推理过滤逻辑的公共头文件中,供 `main.cpp` 设置、`rknn.cpp` 读取。
3. 不改 YOLO 后处理、NMS、阈值、类别编码和上传 JSON,只改 workspace 过滤判定。
4.`rknn.cpp::print_object_detect_result` 中,把直接判断:
```cpp
if (!is_point_in_workspace(left, top, right, bottom)) {
...
continue;
}
```
调整成先计算原始位置关系,再根据 `-R` 反转:
```cpp
bool in_workspace = is_point_in_workspace(left, top, right, bottom);
bool pass_workspace = ReverseWorkspace ? !in_workspace : in_workspace;
if (!pass_workspace) {
...
continue;
}
```
这样 `-R` 只改变“是否允许上报”,不改变多边形算法本身。
5. 低置信度日志里的 workspace 判断也需要同步使用同一个通过规则。否则开启 `-R` 后,低置信度日志仍会按原来的“区域内”记录 `weak_present`,和上报语义不一致。
6. 日志名称建议保留现有兼容字段,同时增加模式信息:
- 正常模式下继续用 `strong_present`、`weak_present`、`filtered_workspace`。
- `-R` 模式下被过滤的目标本质是“命中排除区域”,建议日志里增加 `workspace_mode=reverse` 或新增 `filtered_reverse_workspace`,便于现场排查。
- 命令行输出的 `in result` / `not in result` 也建议区分“在多边形内”和“通过过滤后可上报”,避免 `-R` 模式下读日志误判。
## 边界约定
- `-R` 单独使用、未传 `-w` 时,当前默认 workspace 是全画面。如果直接反转,会变成全画面都被排除,导致无目标上报。建议实现时明确处理:
- 推荐方案:`-R` 必须配合 `-w` 使用;如果未传 `-w`,启动时报错并退出。
- 备选方案:未传 `-w` 时忽略 `-R` 并打印警告。这个更宽松,但容易让现场误以为反向过滤已生效。
- 多边形仍使用目标框中心点判断,不改成框与区域相交判断。这样和现有 `-w` 行为保持一致。
- `-P/--time-period`、阈值 `-r`、心跳、G1000 截图通知、同 `class_idx` 合并逻辑都不需要变化。
## 需要改动的文件
- `main.cpp`
- `long_options` 增加 `-R` 对应长参数。
- `getopt_long_only` 的短参数串加入 `R`。
- `case 'R'` 中设置全局反向开关。
- `print_usage` 的帮助信息补充 `-R` 说明。
- `vertix.h` / `vertix.cpp` 或其他公共配置位置
- 声明和定义反向 workspace 开关。
- 可选:封装一个 `is_box_allowed_by_workspace(...)`,把反转逻辑集中起来,避免 `rknn.cpp` 多处重复判断。
- `rknn.cpp`
- 上报候选过滤处使用统一的 `pass_workspace`。
- 低置信度 `weak_present` / `filtered_low_conf` 日志处同步使用统一规则。
- 日志追加 `workspace_mode=normal|reverse` 或新增反向过滤事件名。
- `README.md` 或运行说明文档
- 增加 `-R` 用法和示例。
## 验证计划
1. 编译验证:
- 按 `docs/cross_compile_wsl_linaro.md` 的 Linaro 路线构建。
- 确认 aarch64 产物正常生成,且不引入高版本 `glibc/libstdc++` 依赖。
2. 行为验证:
- 不带 `-R``-w` 内目标上报,外部目标过滤,行为和当前版本一致。
- 带 `-R -w ...``-w` 内目标过滤,外部目标上报。
- 带 `-R` 但不带 `-w`:按最终选定边界策略报错或警告。
3. 日志验证:
- 反向模式下能看出过滤原因是命中排除区域。
- `upload_positive` 和 `upload_positive_payload` 只出现于通过反向过滤后的区域外目标。
## 历史线索
`updata/main.cpp` 里曾出现过 `--reverse-detect` 和 `ReverseDetectBox = 1`,但当前主线 `main.cpp/rknn.cpp/vertix.*` 没有完整接入该变量。后续实现可以参考命名,但不要直接认为旧目录已经完成当前需求。
## 实现状态
已按本文方案实现:
- `main.cpp`:新增 `-R/--reverse-workspace`,并要求必须配合 `-w/--workspace` 使用。
- `vertix.cpp` / `vertix.h`:新增 `ReverseWorkspace` 开关和 workspace 模式说明函数。
- `rknn.cpp`:强置信上报候选和低置信日志都按 `ReverseWorkspace ? !in_workspace : in_workspace` 判定。
- `README.md`:补充 `-R` 参数、示例和日志说明。
构建验证已通过:
```text
wsl -d Ubuntu bash -lc "cd /mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference/build-aarch64 && cmake /mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference -DCMAKE_TOOLCHAIN_FILE=/mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference/toolchain-aarch64.cmake && make -j16 && file yolov5"
```
输出产物为 `ELF 64-bit LSB executable, ARM aarch64`。构建过程中出现 `Clock skew detected` 提示,属于 Windows/WSL 时间戳差异提示,不是本次代码编译错误。