OrangePi3588Media/docs/bugfix/002-scrfd-cpp-implementation.md

87 lines
2.2 KiB
Markdown
Raw Permalink 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.

# SCRFD C++ 实现完善
## 实现内容
完善了 `ai_scrfd` 插件的 C++ 实现,包括:
### 1. 输入预处理
- 双线性插值 resize 到 640x640
- 支持 RGB/BGR 格式转换
- DMA 缓冲区同步
### 2. 推理流程
- 使用 `InferBorrowed` 进行零拷贝推理
- UINT8 输入RKNN 内部自动量化到 INT8
- `pass_through=0` 让 RKNN 处理类型转换
### 3. 后处理逻辑
- **维度处理**: 适配 SCRFD 500M (v1.4.1) 的输出格式
- scores: `[1, 12800/3200/800, 1, 1]` (2 channels: bg, fg)
- bboxes: `[1, 12800/3200/800, 4, 1]` (dx, dy, dw, dh)
- keypoints: `[1, 12800/3200/800, 10, 1]` (5 points x 2 coords)
- **解码逻辑**:
- Score: sigmoid(bg_score - fg_score) 获取前景概率
- BBox: anchor中心 + 偏移量exp(dw/dh) 解码宽高
- Keypoints: anchor中心 + 相对偏移量
- **坐标映射**: 从 640x640 映射回原图分辨率
### 4. NMS (非极大值抑制)
- 按置信度排序
- IoU 阈值 0.4 去除重叠检测框
- 限制最大检测数量 (默认 50)
## 关键代码片段
```cpp
// Score解码 (sigmoid)
float score = 1.0f / (1.0f + std::exp(bg_score - fg_score));
// BBox解码 (相对于anchor)
float cx = anchor.cx + dx * stride;
float cy = anchor.cy + dy * stride;
float w = std::exp(dw) * stride;
float h = std::exp(dh) * stride;
```
## 配置参数
```json
{
"id": "scrfd",
"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"
}
```
## 注意事项
1. **模型版本**: 使用 SCRFD 500M v1.4.1b16 (静态形状)
- 新版本 v2.3.2 使用动态形状C API 不支持
2. **输入格式**:
- 模型训练使用 BGR但代码默认使用 RGB
- 通过 `input_format` 参数控制
3. **性能**:
- 16800 个 anchor 需要遍历,后处理有一定开销
- 可调整 `conf_thresh` 提前过滤低置信度候选框
## 测试结果
```
[ai_scrfd] Frame 1: detected 50 faces, best score=1.000000
[ai_scrfd] Frame 2: detected 50 faces, best score=1.000000
...
```
- 推理正常,无崩溃
- 检测到多个人脸(繁忙街道场景)
- 输出包含 bbox 和 5 个关键点