OrangePi3588Media/docs/design/detection_parameters_guide.md

20 KiB
Raw Blame History

人脸检测参数配置指南

本文档详细说明人脸检测节点(ai_face_det, ai_scrfd, ai_scrfd_sliding)中的核心后处理参数及其对检测结果的影响。


参数概览

参数名 类型 默认值 范围 说明
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)

if (score < cfg_.conf_thresh) continue;

在 RetinaFace 后处理中 (ai_face_det_node.cpp:784)

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)

detections = ApplyNMS(detections, cfg_.nms_thresh);

NMS 算法逻辑 (ai_face_det_node.cpp:156-167)

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)

if (detections.size() > static_cast<size_t>(cfg_.max_faces)) {
    detections.resize(cfg_.max_faces);
}

在 RetinaFace 后处理中 (ai_face_det_node.cpp:840)

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 节点)

{
  "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 节点)

{
  "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 节点)

{
  "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)

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
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 闸机、通道,减少拒识

代码实现

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 保持一致或识别节点略小。


参数说明

参数 默认值 说明
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 (输入归一化)

两种归一化方式

方式一:缩放+偏移(简单)

{
  "normalize": {
    "scale": 0.0078125,
    "bias": 0.0
  }
}

公式:output = input * scale + bias

方式二:均值+标准差(标准)

{
  "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 人脸识别配置示例

{
  "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 检测+识别完整流程配置

{
  "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,节点会根据输入分辨率自动计算窗口。

窗口格式

{
  "x": 0,      // 窗口左上角 X 坐标
  "y": 0,      // 窗口左上角 Y 坐标  
  "w": 960,    // 窗口宽度
  "h": 1080    // 窗口高度
}

窗口设计原则

  • 窗口之间应有适当重叠,避免漏检
  • 窗口尺寸建议接近 640x640 的倍数resize 后变形较小)
  • 对于 16:9 视频,水平分割效果较好

5.4 不同分辨率配置参考

1080p (1920×1080) - 推荐2窗口

{
  "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窗口

{
  "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) 等更高分辨率,可以增加窗口数量:

{
  "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 配置示例

{
  "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 次模型推理
  • 分辨率越高,窗口数越多:需要在检测效果和性能之间平衡
  • 建议窗口数
    • 1080p2 个窗口
    • 1440p2 个窗口(或 4 个窗口用于更精细检测)
    • 4K3-4 个窗口

5.7 滑动窗口检测常见问题

Q7: 窗口边缘的人脸被分割成两半?

解决方法

  • 增加窗口重叠区域(如窗口 0 结束于 1000窗口 1 开始于 900
  • NMS 会自动合并重复检测

Q8: 远处人脸还是检测不到?

解决方法

  • 增加窗口数量,让每个窗口覆盖更小区域
  • 降低 conf_thresh 让更多候选框通过
  • 考虑使用更高分辨率摄像头

Q9: 检测延迟增加?

解决方法

  • 减少窗口数量
  • 降低 max_faces 减少后处理负担
  • 使用更高性能硬件

六、综合配置建议

6.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窗口 远距离检测

6.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,避免运行时查询数据库

相关文档