2.2 KiB
2.2 KiB
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)
- scores:
-
解码逻辑:
- Score: sigmoid(bg_score - fg_score) 获取前景概率
- BBox: anchor中心 + 偏移量,exp(dw/dh) 解码宽高
- Keypoints: anchor中心 + 相对偏移量
-
坐标映射: 从 640x640 映射回原图分辨率
4. NMS (非极大值抑制)
- 按置信度排序
- IoU 阈值 0.4 去除重叠检测框
- 限制最大检测数量 (默认 50)
关键代码片段
// 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;
配置参数
{
"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"
}
注意事项
-
模型版本: 使用 SCRFD 500M v1.4.1b16 (静态形状)
- 新版本 v2.3.2 使用动态形状,C API 不支持
-
输入格式:
- 模型训练使用 BGR,但代码默认使用 RGB
- 通过
input_format参数控制
-
性能:
- 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 个关键点