safesight-edge/docs/design/detection_parameters_guide.md

933 lines
26 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.

# 检测参数配置指南
本文档说明当前项目中与“检测效果”和“实时性”最相关的参数,覆盖:
- 人脸检测
- 人脸识别
- 车间劳保鞋两阶段检测
- 颜色判断与告警稳定性
---
## 一、人脸检测参数概览
| 参数名 | 类型 | 默认值 | 范围 | 说明 |
|--------|------|--------|------|------|
| `conf_thresh` | float | 0.5/0.6/0.7 | 0.0 ~ 1.0 | 置信度阈值,过滤低置信度候选框 |
| `nms_thresh` | float | 0.4 | 0.0 ~ 1.0 | NMS IoU 阈值,控制重复框去重力度 |
| `max_faces` | int | 10/50 | ≥ 1 | 单帧最大返回人脸数 |
---
## 1. conf_thresh (置信度阈值)
### 含义
模型对检测到的人脸的置信度confidence score阈值。神经网络在推理时会对每个候选框输出一个置信度分数表示该位置存在人脸的确定性程度。
### 对检测结果的影响
| 设置 | 效果 | 适用场景 |
|------|------|----------|
| **调高** (如 0.7) | 减少误检,只保留高置信度人脸 | 高精度需求场景(门禁、考勤) |
| **调低** (如 0.2) | 增加检出率,更多弱特征人脸被检测 | 弱光、远距离、小目标场景 |
### 注意事项
- 值过高可能导致**漏检**:模糊人脸、侧脸、小人脸可能被过滤
- 值过低可能导致**误检**:背景中的类似人脸的纹理可能被误判
### 代码实现
在 SCRFD 后处理中 (`ai_scrfd_node.cpp:282`)
```cpp
if (score < cfg_.conf_thresh) continue;
```
在 RetinaFace 后处理中 (`ai_face_det_node.cpp:784`)
```cpp
if (score < cfg.conf_thresh) continue;
```
---
## 2. nms_thresh (NMS IoU 阈值)
### 含义
非极大值抑制Non-Maximum Suppression的 IoUIntersection over Union交并比阈值。
**NMS 的作用**:同一个真实人脸可能被多个 anchor/候选框检测到NMS 用于去除重叠的重复检测框,只保留最优的一个。
**IoU 计算**
```
IoU = 两个框的交集面积 / 两个框的并集面积
```
### 对检测结果的影响
| 设置 | 效果 | 适用场景 |
|------|------|----------|
| **调高** (如 0.6) | 保留更多重叠框,对密集人脸友好 | 多人密集场景(会议室、教室) |
| **调低** (如 0.3) | 严格去重,只保留最优框 | 单人场景、需要精确框选 |
### 注意事项
- 值过高:同一人脸可能返回多个重叠框
- 值过低:密集人脸场景可能误删相邻的不同人脸
### 代码实现
在 SCRFD 后处理中 (`ai_scrfd_node.cpp:172`)
```cpp
detections = ApplyNMS(detections, cfg_.nms_thresh);
```
NMS 算法逻辑 (`ai_face_det_node.cpp:156-167`)
```cpp
void NmsSorted(const std::vector<Rect>& boxes, const std::vector<float>& scores,
float nms_thresh, std::vector<int>& keep) {
for (...) {
bool suppressed = false;
for (int kept : keep) {
if (IoU(boxes[idx], boxes[kept]) > nms_thresh) {
suppressed = true; // 被已保留的框抑制
break;
}
}
if (!suppressed) keep.push_back(idx);
}
}
```
---
## 3. max_faces (最大人脸数)
### 含义
单帧图像中最多返回的人脸检测数量限制。
### 对检测结果的影响
| 设置 | 效果 | 性能影响 |
|------|------|----------|
| **调高** (如 50) | 可检测更多人脸,不遗漏密集场景目标 | 增加后处理开销RGA/OSD 绘制负载增大 |
| **调低** (如 5) | 仅保留置信度最高的前几个人脸 | 减少计算量,提升实时性 |
### 注意事项
- 当画面中出现超过 `max_faces` 数量的人脸时,系统会按置信度排序,只保留前 N 个
- 设置过大可能导致 RGA 任务堆积,引起 OSD 绘制卡顿
### 代码实现
在 SCRFD 后处理中 (`ai_scrfd_node.cpp:174-176`)
```cpp
if (detections.size() > static_cast<size_t>(cfg_.max_faces)) {
detections.resize(cfg_.max_faces);
}
```
在 RetinaFace 后处理中 (`ai_face_det_node.cpp:840`)
```cpp
const int out_n = std::min<int>(cfg.max_faces, static_cast<int>(keep.size()));
```
---
## 推荐配置
### 按应用场景
| 场景 | conf_thresh | nms_thresh | max_faces | 说明 |
|------|-------------|------------|-----------|------|
| **高精度门禁/考勤** | 0.6 ~ 0.7 | 0.4 | 5 ~ 10 | 减少误识别,确保准确率 |
| **多人大场景** (会议室/教室) | 0.4 ~ 0.5 | 0.4 ~ 0.5 | 20 ~ 50 | 平衡检出率和去重效果 |
| **实时性优先** | 0.5 | 0.4 | 10 | 减少后处理开销 |
| **弱光/远距离/小目标** | 0.3 ~ 0.4 | 0.3 | 10 ~ 20 | 提高检出率,但需容忍一定误检 |
| **单人视频通话** | 0.6 | 0.4 | 1 ~ 3 | 最小化处理开销 |
### 按硬件性能
| 设备性能 | max_faces 建议 | 优化策略 |
|----------|----------------|----------|
| **RK3588 高性能模式** | 20 ~ 50 | 可同时处理多路高清视频 |
| **RK3588 平衡模式** | 10 ~ 20 | 适当降低分辨率和检测频率 |
| **RK3566/RK3568** | 5 ~ 10 | 降低输入分辨率,提高 conf_thresh 减少候选框 |
---
## 参数联动关系
这三个参数需要协同调整:
1. **提高 `conf_thresh`** → 候选框数量减少 → 可降低 `max_faces` → NMS 压力减小
2. **降低 `conf_thresh`** → 候选框数量增加 → 可能需要提高 `max_faces` → NMS 压力增大
3. **密集场景**:适当提高 `nms_thresh` 避免误删相邻人脸,同时确保 `max_faces` 足够大
---
## 配置示例
### SCRFD 配置 (`ai_scrfd` 节点)
```json
{
"type": "ai_scrfd",
"model_path": "./models/face_det_scrfd_500m_640_rk3588.rknn",
"conf_thresh": 0.5,
"nms_thresh": 0.4,
"max_faces": 50,
"output_landmarks": true,
"input_format": "rgb"
}
```
### RetinaFace 配置 (`ai_face_det` 节点)
```json
{
"type": "ai_face_det",
"model_path": "./models/face_det_scrfd_500m_640_rk3588.rknn",
"conf": 0.7,
"nms": 0.4,
"max_faces": 10,
"output_landmarks": true,
"input_format": "rgb"
}
```
### 分区域检测配置 (`ai_face_det_zoned` 节点)
```json
{
"type": "ai_face_det_zoned",
"model_path": "./models/face_det_scrfd_500m_640_rk3588.rknn",
"conf": 0.6,
"nms": 0.4,
"max_faces": 10,
"output_landmarks": true
}
```
---
## 调试建议
1. **先调 conf_thresh**:从默认值开始,观察是否漏检或误检
2. **再调 nms_thresh**:在密集人脸场景测试,确保既不重复框选也不漏检
3. **最后调 max_faces**:根据实际场景人数和硬件性能调整
### 日志查看
启动时节点会打印当前参数:
```
[ai_face_det] start id=face_det conf=0.7 nms=0.4 max_faces=10
[ai_scrfd] start id=scrfd conf=0.5 nms=0.4 max_faces=50
```
---
## 常见问题
### Q1: 为什么检测到的人脸框会抖动/闪烁?
**可能原因**
- `conf_thresh` 设置过低,边缘候选框置信度波动导致时有时无
- `nms_thresh` 过低,相邻帧选择不同的 anchor
**解决方法**:适当提高 `conf_thresh` 或调整 `nms_thresh`
### Q2: 密集场景漏检严重怎么办?
**解决方法**
- 降低 `conf_thresh` 到 0.4 左右
- 提高 `max_faces` 到 30 以上
- 适当提高 `nms_thresh` 到 0.5,避免相邻人脸被抑制
### Q3: OSD 绘制卡顿RGA 任务堆积?
**解决方法**
- 降低 `max_faces` 减少绘制负载
- 提高 `conf_thresh` 减少检测数量
---
## 四、人脸识别参数 (`ai_face_recog`)
人脸识别当前已经支持节流参数,适合车间这类“人比较稳定、不需要高频重复识别”的场景。
### 1. 关键参数
| 参数 | 当前建议 | 作用 |
|------|----------|------|
| `infer_fps` | `2` | 人脸识别频率 |
| `infer_phase_ms` | `120` 左右 | 与其它 AI 节点错峰 |
| `max_faces` | `50` | 单帧最多识别多少张脸 |
| `threshold.accept` | `0.45` | 识别通过阈值 |
| `threshold.margin` | `0.05` | Top1/Top2 相似度边界 |
### 2. 调参原则
- 完整流程 FPS 不够:优先降低 `infer_fps`
- 识别太慢才出结果:适当提高 `infer_fps`
- 误识别偏多:提高 `threshold.accept`
- 经常识别成 unknown适当降低 `threshold.accept`
### 3. 典型配置示例
```json
{
"id": "face_recog",
"type": "ai_face_recog",
"infer_fps": 2,
"infer_phase_ms": 120,
"max_faces": 50,
"threshold": {
"accept": 0.45,
"margin": 0.05
}
}
```
---
## 五、车间劳保鞋检测参数(当前主线)
当前项目的鞋检测不再走“人鞋一体全图检测”思路,而是:
```text
ai_yolo(person only)
-> tracker(person only)
-> ai_shoe_det(dynamic foot roi)
-> logic_gate(person_shoe_check)
-> logic_gate(ppe_boots_check)
-> alarm
```
也就是说,鞋子相关参数不再只看一个 `detect.conf`,而是分成 4 层:
1. 人体前级参数
2. 鞋检测参数
3. 颜色判断参数
4. 告警稳定性参数
### 1. 人体前级参数(`ai_yolo`
| 参数 | 当前建议 | 作用 |
|------|----------|------|
| `conf` | `0.35` | 人体候选阈值 |
| `nms` | `0.45` | 人框去重 |
| `infer_fps` | `2` | 人检频率 |
| `bbox_expand.bottom` | `0.16` | 补偿高机位下漏脚问题 |
调参原则:
- 人框太紧、脚经常漏在外面:优先增大 `bbox_expand.bottom`
- 人漏检明显:适当降低 `conf`
- 周期性卡顿:先不要盲目提 `infer_fps`
### 2. 鞋检测参数(`ai_shoe_det`
| 参数 | 当前建议 | 作用 |
|------|----------|------|
| `conf` | `0.15 ~ 0.22` | 鞋候选召回阈值 |
| `nms` | `0.45` | 鞋框去重 |
| `infer_fps` | `2` | 鞋检频率 |
| `dynamic_roi.max_rois` | `3` | 单帧最多处理多少人 |
| `dynamic_roi.min_person_height` | `60` | 过滤太远的人 |
| `dynamic_roi.max_box_area_ratio` | `0.60` | 过滤接近整块脚区的大误框 |
| `x_offset/y_offset/width_scale/height_scale` | 见推荐配置 | 控制脚部 ROI 形状 |
为什么 `shoe_det.conf` 会落在 `0.15 ~ 0.22`
- 当前场景是高机位、小目标、遮挡多
- 如果把鞋阈值直接提到常规检测项目里的 `0.4~0.5`
通常先发生的是严重漏检,而不是“更稳”
- 当前链路依赖:
- 低阈值鞋候选召回
- 人鞋空间关联
- 鞋颜色判断
- 告警去抖和冷却
所以这里的思路是:
```text
前面低阈值多召回,后面多级逻辑再收紧
```
### 3. 颜色判断参数(`logic_gate -> ppe_boots_check`
| 参数 | 当前建议 | 作用 |
|------|----------|------|
| `method` | `brightness` | 颜色判断方式 |
| `dark_threshold` | `90` | 黑鞋/深色鞋阈值 |
| `roi_expand` | `1.0` | 颜色分析区域放大比例 |
调参原则:
- 黑鞋也经常被判成违规:适当提高 `dark_threshold`
- 拖鞋/浅色鞋经常被放过:适当降低 `dark_threshold`
### 4. 告警稳定性参数(`alarm`
| 参数 | 当前建议 | 作用 |
|------|----------|------|
| `min_score` | `0.30` | 蓝框进入告警的最低分数 |
| `min_hits` | `2` | 2 秒内至少出现几次 |
| `hit_window_ms` | `2000` | 命中窗口 |
| `min_duration_ms` | `800` | 持续多久才报警 |
| `cooldown_ms` | `15000` | 告警后的冷却时间 |
调参原则:
- 蓝框已经稳定出现,但不告警:先看 `min_score / min_hits / min_duration_ms`
- 告警过于频繁:提高 `cooldown_ms`
- 闪一下就报警:提高 `min_duration_ms`
### 推荐调参顺序
1. 先让人框稳定,脚不要漏
2. 再让鞋框能稳定出来
3. 再调颜色判断黑白边界
4. 最后再调告警节流
### 六、实施人员速查
如果只记一小部分参数,优先记下面这些:
| 想解决的问题 | 先改哪个参数 |
|--------------|--------------|
| 人脸太吃性能 | `face_det.infer_fps`、`face_recog.infer_fps` |
| 人框太紧、鞋 ROI 裁偏 | `person_det.bbox_expand.bottom` |
| 鞋漏报 | `shoe_det.conf`、`shoe_assoc.min_shoe_score` |
| 蓝框误报多 | `shoe_det.conf`、`dynamic_roi.max_box_area_ratio` |
| 黑鞋被误报 | `dark_threshold` |
| 告警太频繁 | `min_duration_ms`、`cooldown_ms` |
不要一开始就只改 `alarm`,否则常常会把“检测问题”误判成“规则问题”。
`ai_face_recog` 节点接收人脸检测结果,提取人脸特征向量并与特征库进行比对,完成人脸识别。
### 4.1 参数概览
| 参数名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| `align` | bool | true | 是否使用5点关键点进行人脸对齐 |
| `emit_embedding` | bool | false | 是否输出特征向量(用于调试) |
| `max_faces` | int | 10 | 单帧最大处理人脸数 |
| `input_format` | string | "rgb" | 输入图像格式rgb/bgr |
| `input_dtype` | string | "uint8" | 输入数据类型uint8/float |
| `threshold.accept` | float | 0.45 | 识别通过阈值,相似度超过此值才接受 |
| `threshold.margin` | float | 0.05 | 边距阈值,最佳与次佳匹配的差距要求 |
| `gallery.backend` | string | "sqlite" | 人脸库后端类型 |
| `gallery.path` | string | "./models/face_gallery.db" | 人脸库文件路径 |
---
### 4.2 align (人脸对齐)
#### 含义
是否使用检测到的5个面部关键点眼睛、鼻子、嘴角进行人脸对齐变换。
#### 对识别效果的影响
| 设置 | 效果 | 适用场景 |
|------|------|----------|
| **true** | 对齐后人脸姿态归一化,提高识别准确率 | 高位摄像头、角度倾斜、侧脸场景 |
| **false** | 直接裁剪人脸区域,计算量略小 | 正面、固定位置场景 |
#### 对齐原理
使用5点关键点与标准模板进行相似变换Similarity Transform
- 标准模板坐标112x112输入左眼(38.29,51.70)、右眼(73.53,51.50)、鼻尖(56.02,71.74)、左嘴角(41.55,92.37)、右嘴角(70.73,92.20)
- 代码实现:`ai_face_recog_node.cpp:851-865`
```cpp
if (cfg->align && face.has_landmarks && model_w_ == 112 && model_h_ == 112) {
const std::array<Point2f, 5> dst = { ... }; // 标准模板
SimilarityTransform t;
InvTransform inv;
if (ComputeSimilarity(face.landmarks, dst, t) && InvertSimilarity(t, inv)) {
WarpFace(src, w, h, stride, inv, face_buf_.data(), model_w_, model_h_, need_swap);
}
}
```
---
### 4.3 threshold.accept (接受阈值)
#### 含义
特征向量相似度阈值,范围 `0.0 ~ 1.0`。只有当待识别人脸与库中某人的相似度超过此值时,才认为是匹配成功。
#### 对识别结果的影响
| 设置 | 效果 | 误识率 | 拒识率 |
|------|------|--------|--------|
| **调高** (如 0.55) | 更严格,只接受高度相似 | 低 | 高 |
| **调低** (如 0.35) | 更宽松,容易匹配 | 高 | 低 |
#### 推荐值
| 场景 | 推荐值 | 说明 |
|------|--------|------|
| **高安全性场景** | 0.50 ~ 0.55 | 门禁、支付,严格控制误识 |
| **一般场景** | 0.45 ~ 0.50 | 考勤、签到,平衡准确率和体验 |
| **快速通行场景** | 0.40 ~ 0.45 | 闸机、通道,减少拒识 |
#### 代码实现
```cpp
const bool accept = (sr.best_person_id >= 0) &&
(sr.best_sim >= cfg->thr_accept) &&
((cfg->thr_margin <= 0.0f) || ((sr.best_sim - sr.second_sim) >= cfg->thr_margin));
```
---
### 4.4 threshold.margin (边距阈值)
#### 含义
要求最佳匹配与次佳匹配的相似度差距至少达到此值,用于排除模糊匹配(如两个人都很像的情况)。设为 `0` 或负数可禁用此检查。
#### 作用示例
假设待识别人脸与库中人员相似度如下:
- 张三(最佳): 0.62
- 李四(次佳): 0.58
- 差距: 0.04
如果 `margin = 0.05`,则 0.04 < 0.05匹配失败标记为 unknown
如果 `margin = 0.03` 0.04 > 0.03,匹配成功(识别为张三)
#### 推荐值
- **0.05**(默认):适合大多数人脸库
- **0.00** 或负数:禁用边距检查,只依赖 accept 阈值
---
### 4.5 max_faces (最大处理人脸数)
#### 含义
单帧最多处理的人脸数量。由于特征提取需要 NPU 推理,此参数直接影响处理延迟。
#### 与检测节点 max_faces 的关系
```
实际处理数 = min(face_det.max_faces, face_recog.max_faces)
```
建议两个节点的 `max_faces` 保持一致或识别节点略小。
---
### 4.6 gallery (人脸库配置)
#### 参数说明
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `backend` | "sqlite" | 后端类型,目前仅支持 sqlite |
| `path` | "./models/face_gallery.db" | 人脸库数据库文件路径 |
| `load_on_start` | true | 启动时加载到内存 |
| `expected_dim` | 512 | 特征向量维度MobileFaceNet 为 512 |
| `dtype` | "auto" | 数据类型auto/float32 |
#### 人脸库管理
人脸库使用 SQLite 存储,包含以下信息:
- `person_id`人员唯一ID
- `name`:人员名称
- `embedding`特征向量512维浮点数
- 可通过 Web 管理接口或脚本添加/删除/更新人脸
---
### 4.7 normalize (输入归一化)
#### 两种归一化方式
**方式一:缩放+偏移(简单)**
```json
{
"normalize": {
"scale": 0.0078125,
"bias": 0.0
}
}
```
公式:`output = input * scale + bias`
**方式二:均值+标准差(标准)**
```json
{
"normalize": {
"mean": [127.5, 127.5, 127.5],
"std": [128.0, 128.0, 128.0]
}
}
```
公式:`output = (input - mean) / std`
#### 默认值
MobileFaceNet 模型通常使用:
- `scale`: 1.0(不对 uint8 输入做缩放,由模型内部处理)
-`mean: [127.5,127.5,127.5], std: [127.5,127.5,127.5]` 归一化到 [-1, 1]
---
### 4.8 人脸识别配置示例
```json
{
"id": "face_recog",
"type": "ai_face_recog",
"role": "filter",
"enable": true,
"model_path": "./models/face_recog_mobilefacenet_arcface_112_rk3588.rknn",
"align": true,
"emit_embedding": false,
"max_faces": 50,
"input_format": "rgb",
"input_dtype": "uint8",
"threshold": {
"accept": 0.45,
"margin": 0.05
},
"gallery": {
"backend": "sqlite",
"path": "./models/face_gallery.db",
"load_on_start": true,
"expected_dim": 512,
"dtype": "auto"
}
}
```
---
### 4.9 检测+识别完整流程配置
```json
{
"graphs": [{
"nodes": [
{
"id": "scrfd",
"type": "ai_scrfd",
"conf_thresh": 0.3,
"nms_thresh": 0.4,
"max_faces": 50,
"output_landmarks": true
},
{
"id": "face_recog",
"type": "ai_face_recog",
"align": true,
"max_faces": 50,
"threshold": { "accept": 0.45, "margin": 0.05 },
"gallery": { "path": "./models/face_gallery.db" }
},
{
"id": "osd",
"type": "osd",
"draw_face_det": true,
"draw_face_bbox": true
}
],
"edges": [
["scrfd", "face_recog"],
["face_recog", "osd"]
]
}]
}
```
---
---
## 五、滑动窗口检测参数 (`ai_scrfd_sliding`)
`ai_scrfd_sliding` 是专为**高分辨率视频**设计的滑动窗口检测节点,通过将画面分割成多个窗口分别检测,有效提升远处小目标的检出率。
### 5.1 节点特性
| 特性 | 说明 |
|------|------|
| **原始分辨率输入** | 直接接收原始图像,保留更多细节 |
| **滑动窗口检测** | 将画面分割成多个窗口,分别检测后合并结果 |
| **保持宽高比** | 每个窗口 resize 到 640x640轻微变形但可接受 |
| **窗口可配置** | 支持自定义窗口数量和位置 |
### 5.2 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `model_path` | string | - | SCRFD 模型路径 |
| `conf_thresh` | float | 0.3 | 置信度阈值 |
| `nms_thresh` | float | 0.4 | NMS IoU 阈值 |
| `max_faces` | int | 50 | 最大检测人脸数 |
| `output_landmarks` | bool | true | 是否输出5点关键点 |
| `windows` | array | 自动计算 | 窗口配置数组 |
### 5.3 窗口配置 (`windows`)
如果不配置 `windows`,节点会根据输入分辨率自动计算窗口。
**窗口格式**
```json
{
"x": 0, // 窗口左上角 X 坐标
"y": 0, // 窗口左上角 Y 坐标
"w": 960, // 窗口宽度
"h": 1080 // 窗口高度
}
```
**窗口设计原则**
- 窗口之间应有适当重叠,避免漏检
- 窗口尺寸建议接近 640x640 的倍数resize 后变形较小)
- 对于 16:9 视频,水平分割效果较好
### 5.4 不同分辨率配置参考
#### 1080p (1920×1080) - 推荐2窗口
```json
{
"windows": [
{"x": 0, "y": 0, "w": 960, "h": 1080},
{"x": 960, "y": 0, "w": 960, "h": 1080}
]
}
```
**说明**
- 窗口 0左半边 960x1080
- 窗口 1右半边 960x1080
- 正好覆盖 1920 宽度,无重叠
- 每个窗口 resize 到 640x640比例 0.89:1
#### 1440p (2560×1440) - 推荐2窗口
```json
{
"windows": [
{"x": 0, "y": 0, "w": 1280, "h": 1440},
{"x": 1280, "y": 0, "w": 1280, "h": 1440}
]
}
```
**说明**
- 窗口 0左半边 1280x1440
- 窗口 1右半边 1280x1440
- 比例 0.89:1与 1080p 一致
#### 更高分辨率 - 增加窗口数
对于 4K (3840×2160) 等更高分辨率,可以增加窗口数量:
```json
{
"windows": [
{"x": 0, "y": 0, "w": 1280, "h": 1080},
{"x": 1280, "y": 0, "w": 1280, "h": 1080},
{"x": 2560, "y": 0, "w": 1280, "h": 1080}
]
}
```
### 5.5 配置示例
```json
{
"id": "scrfd_sliding",
"type": "ai_scrfd_sliding",
"role": "filter",
"enable": true,
"model_path": "./models/face_det_scrfd_500m_640_rk3588.rknn",
"conf_thresh": 0.3,
"nms_thresh": 0.4,
"max_faces": 50,
"output_landmarks": true,
"windows": [
{"x": 0, "y": 0, "w": 960, "h": 1080},
{"x": 960, "y": 0, "w": 960, "h": 1080}
]
}
```
### 5.6 性能考量
- **窗口数 = 推理次数**2 个窗口 = 2 次模型推理
- **分辨率越高,窗口数越多**:需要在检测效果和性能之间平衡
- **建议窗口数**
- 1080p2 个窗口
- 1440p2 个窗口(或 4 个窗口用于更精细检测)
- 4K3-4 个窗口
### 5.7 滑动窗口检测常见问题
#### Q7: 窗口边缘的人脸被分割成两半?
**解决方法**
- 增加窗口重叠区域(如窗口 0 结束于 1000窗口 1 开始于 900
- NMS 会自动合并重复检测
#### Q8: 远处人脸还是检测不到?
**解决方法**
- 增加窗口数量,让每个窗口覆盖更小区域
- 降低 `conf_thresh` 让更多候选框通过
- 考虑使用更高分辨率摄像头
#### Q9: 检测延迟增加?
**解决方法**
- 减少窗口数量
- 降低 `max_faces` 减少后处理负担
- 使用更高性能硬件
---
## 六、OSD 显示参数 (`osd`)
OSD 节点负责在视频上绘制检测结果(边界框、文字标签等)。
### 6.1 参数说明
| 参数名 | 类型 | 默认值 | 范围 | 说明 |
|--------|------|--------|------|------|
| `draw_bbox` | bool | true | true/false | 绘制普通检测框YOLO等 |
| `draw_text` | bool | true | true/false | 绘制文字标签 |
| `draw_face_det` | bool | true | true/false | 绘制人脸检测框(青色) |
| `draw_face_recog` | bool | true | true/false | 绘制人脸识别框(红色=陌生人,绿色=已识别) |
| `draw_face_bbox` | bool | true | true/false | 绘制人脸边界框(总开关) |
| `line_width` | float | 2.0 | ≥1.0 | 框线宽度像素最小1像素 |
| `font_scale` | float | 1.0 | ≥0.5 | 字体缩放比例基础5×7像素 |
| `use_rga_bbox` | bool | true | true/false | 使用RGA硬件绘制RK3588 |
### 6.2 配置示例
```json
{
"id": "osd",
"type": "osd",
"role": "filter",
"enable": true,
"draw_bbox": true,
"draw_text": true,
"draw_face_det": true,
"draw_face_recog": false,
"draw_face_bbox": true,
"line_width": 1.0,
"font_scale": 1.0,
"use_rga_bbox": false,
"labels": ["person", "face"]
}
```
### 6.3 注意事项
1. **框线宽度**:由于 `line_width` 转整数后最小为 1设置 0.5 和 1.0 效果相同
2. **字体大小**:基础字体为 5×7 像素,`font_scale` 控制缩放和字间距
3. **颜色说明**
- 人脸检测框:`{0, 180, 180}`(深青色)
- 人脸识别人脸:红色(`{255, 0, 0}`)表示陌生人,绿色(`{0, 255, 0}`)表示已识别
4. **重叠问题**:当 `draw_face_det``draw_face_recog` 同时开启时,两个框坐标相同会重叠,建议只开启一个
---
## 七、综合配置建议
### 7.1 场景配置速查表
| 场景 | 检测节点 | 关键参数 | 说明 |
|------|----------|----------|------|
| **门禁/考勤** | `ai_face_det` | conf=0.7, max_faces=5 | 近距离,高精度 |
| **车间/厂房** | `ai_scrfd_sliding` | 2窗口 | 高位摄像头,大透视 |
| **会议室** | `ai_scrfd` | conf=0.4, max_faces=50 | 多人场景 |
| **户外/街道** | `ai_scrfd_sliding` | 2-4窗口 | 远距离检测 |
### 7.2 分辨率配置对照表
| 分辨率 | 检测节点 | 输入处理 | 建议 |
|--------|----------|----------|------|
| 720p | `ai_scrfd` | 前置缩放至640 | 通用配置 |
| 1080p | `ai_scrfd_sliding` | 2窗口(960x1080) | 滑动窗口检测 |
| 1440p | `ai_scrfd_sliding` | 2窗口(1280x1440) | 滑动窗口检测 |
| 4K | `ai_scrfd_sliding` | 3-4窗口 | 更多窗口提升精度 |
---
## 八、常见问题汇总
### Q1: 检测框抖动/闪烁
**可能原因**
- `conf_thresh` 设置过低,边缘候选框置信度波动
- `nms_thresh` 过低,相邻帧选择不同 anchor
**解决方法**:适当提高 `conf_thresh` 或调整 `nms_thresh`
### Q2: 密集场景漏检严重?
**解决方法**
- 降低 `conf_thresh` 到 0.4 左右
- 提高 `max_faces` 到 30 以上
- 适当提高 `nms_thresh` 到 0.5
### Q3: OSD 绘制卡顿?
**解决方法**
- 降低 `max_faces` 减少绘制负载
- 提高 `conf_thresh` 减少检测数量
### Q4: 识别准确率不高?
**可能原因及解决方法**
1. **对齐问题**:确保 `align: true`,且检测节点 `output_landmarks: true`
2. **阈值不合适**:调整 `threshold.accept`,根据实际测试确定最佳值
3. **人脸库质量**:确保库中人脸照片清晰、正面、光线均匀
4. **检测框质量**:适当提高检测 `conf_thresh`,过滤低质量检测框
#### Q5: 远距离/小目标识别效果差?
**解决方法**
- 提高检测 `conf_thresh`,让只有清晰的人脸进入识别
- 检查摄像头分辨率,确保人脸区域至少 60x60 像素
- 考虑使用更高清的摄像头或调整安装角度
#### Q6: 识别延迟高?
**优化方法**
- 降低 `max_faces`,减少单帧处理数量
- 提高检测 `conf_thresh`,减少候选框
- 确保 `gallery.load_on_start: true`,避免运行时查询数据库
---
## 相关文档
- [SCRFD 模型规格说明](../scrfd_500m_640_spec.md)
- [YOLO 检测参数配置](../config_guide.md)
- [DAG 节点与边说明](./dag_graph_node_edge.md)
- [MobileFaceNet 模型说明](../models.md)