933 lines
26 KiB
Markdown
933 lines
26 KiB
Markdown
# 检测参数配置指南
|
||
|
||
本文档说明当前项目中与“检测效果”和“实时性”最相关的参数,覆盖:
|
||
|
||
- 人脸检测
|
||
- 人脸识别
|
||
- 车间劳保鞋两阶段检测
|
||
- 颜色判断与告警稳定性
|
||
|
||
---
|
||
|
||
## 一、人脸检测参数概览
|
||
|
||
| 参数名 | 类型 | 默认值 | 范围 | 说明 |
|
||
|--------|------|--------|------|------|
|
||
| `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)的 IoU(Intersection 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/scrfd_500m_640.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/RetinaFace_mobile320.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/RetinaFace_mobile320.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/mobilefacenet_arcface.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/scrfd_500m_640.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 次模型推理
|
||
- **分辨率越高,窗口数越多**:需要在检测效果和性能之间平衡
|
||
- **建议窗口数**:
|
||
- 1080p:2 个窗口
|
||
- 1440p:2 个窗口(或 4 个窗口用于更精细检测)
|
||
- 4K:3-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)
|