ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

03-SCRFD人脸检测与关键点

2026/8/15 23:26:28 拓冰建站 浏览量
03-SCRFD人脸检测与关键点 SCRFD 人脸检测与五官关键点从 ROI 到可对齐几何本文讲透一件事在本项目里一张或一块BGR 图如何变成 人脸框 分数 五个关键点。重点是 SCRFD 的 左上角 pad 预处理不是居中 letterbox、多 stride 解码公式、全图 Tile 补检、以及人体 ROI 内检脸时的坐标叠层。关键点质量直接决定后续对齐框对了点错了识别会「自信地错」。1. 人脸检测要交付什么业务侧一次成功的检测至少包含box: (x, y, width, height) // 原图或当前坐标系score: floatkps: Point2f[5] // 左眼、右眼、鼻尖、左嘴角、右嘴角顺序必须与对齐模板一致。本项目 ArcFace 对齐使用 InsightFace 常见顺序写反左右眼会导致 112×112 花屏般扭曲。默认权重路径为./models/scrfd_2.5g_bnkps.onnxbnkps表示带关键点。输入边长 SCRFD 路径为 640YuNet 回退为 320。2. 为何常在人体 ROI 内检脸两条路线路线优点风险全图直接 SCRFD实现简单4K 小人脸、算力高、海报脸多人体框 ROI 内检搜索空间小符合「脸长在人身上」人体框切掉额头/下巴会丢脸跟踪路径上 ROI clamp 后的人体框本身不做外扩。这与「经验上上下左右 pad」的科普叙述不同——本项目选择更紧的 ROI换取更少邻人探入代价是人体框偏短时可能切脸。配置上用人脸分数阈值默认约 0.40与过大脸过滤补偿。图在人体检测框内裁 ROI 做人脸检测本项目跟踪路径默认不外扩仅 clamp 到画幅减少邻脸入侵。对每个人体框clamp ROI跳过32×32优先 动态 batch 一次跑多个 ROI把相对 ROI 的box/kps加上roi.x/roi.y回到全图过大脸过滤 去掉过大脸海报、误检。失败模式 只平移了 box、忘了 kps → 对齐用错点ROI 过小未放大 → 远脸永远无点。3. SCRFD 预处理左上角 pad不是居中YOLO 人体常用 居中 letterboxSCRFD 在本项目明确是 InsightFace 风格 resize 左上角粘贴——不是居中 Letterbox要点等比缩放使较长边贴合 目标边长方输入黑边在右/下有效内容贴在左上角(0,0)det_scale new_h / src.rows与宽度缩放一致因等比解码时用inv_scale 1/det_scale把网络坐标乘回预处理前图。左上角 pad 预处理// InsightFace SCRFD左上角 pad不是居中 Letterboxvoidscrfd_prepare_input_bgr(constcv::Matsrc,inttarget_size,cv::Matout,doubledet_scale){constdoubleim_ratio(double)src.rows/(double)src.cols;intnew_w0,new_h0;if(im_ratio1.0){new_htarget_size;new_w(int)std::lround((double)new_h/im_ratio);}else{new_wtarget_size;new_h(int)std::lround((double)new_w*im_ratio);}new_wstd::max(1,std::min(target_size,new_w));new_hstd::max(1,std::min(target_size,new_h));cv::Mat resized;cv::resize(src,resized,cv::Size(new_w,new_h));outcv::Mat::zeros(target_size,target_size,CV_8UC3);resized.copyTo(out(cv::Rect(0,0,new_w,new_h)));// 贴在 (0,0)det_scale(double)new_h/(double)std::max(1,src.rows);}数值例子ROI 200×500 → 640im_ratio 500/200 2.5 1new_h 640, new_w round(640/2.5) 256det_scale 640/500 1.28640 画布左上 256×640 为有效图右侧 384 列为黑。若错误地用居中 pad 训练/导出假设左上原点框与点会系统性偏移半个 pad——典型「全往右下漂」。4. 多尺度锚点与解码公式SCRFD 在多个 feature stride 上预测。每个位置 2 个 anchor。中心cx x * stride, cy y * stride框为 距离中心的左右上下距离distance再乘 stridex0 (cx - dlstride) * inv_scaley0 (cy - dtstride) * inv_scalex1 (cx drstride) * inv_scaley1 (cy dbstride) * inv_scale关键点同理kx (cx oxstride) * inv_scaleky (cy oystride) * inv_scale其中inv_scale 1/det_scale把网络输入坐标还原到 预处理前的图ROI 或全图缩放图。手算例子stride8特征格(x,y)(10,20)→cx80, cy160。dl,dt,dr,db 2,3,2.5,4网络输出→ 乘 8 得16,24,20,32。det_scale0.5inv2x0(80-16)*2128, y0(160-24)*2272x1(8020)*2200, y1(16032)*2384脸约 72×112预处理前坐标某关键点偏移(1.5, -0.5)kx(801.5*8)2 184, ky(160-0.58)*2 312图SCRFD 输出人脸框与五点——左眼、右眼、鼻尖、左嘴角、右嘴角点序必须与对齐模板一致。5. 分数阈值与「能检 ≠ 能识别」ROI 配置默认人脸分数阈值约 0.40。全图路径里常见更低阈如 0.250.3以提高召回。分层建议人脸短边原图像素检测识别20多半噪声不可用2040存在性极不稳4080较可靠正脸可试80稳适合锁定过大脸过滤短边超过max_face_short_ratio × min(帧宽,帧高)或相对同伴过大同伴倍数多半是海报/误检。6. 全图 Tileoverlap 0.25NMS 0.45当允许 tile 且分辨率够大时走滑窗人脸检测与人体 Tile 的差异门槛同样约 1280×720但 4 格阈是 2400×1350不是 3840tile 保持矩形按 base 各向 ×1.25不强制正方形最小块 160人体侧常 320框与 每个关键点 都要加 ROI 原点。合并策略先对缩小后的全图跑一次 SCRFD若失败或空 → 直接 tile若只找到 ≤1 张脸且图够大 → 补充 tile再与原结果合并nms_dets_inplace(merged, 0.40)。人脸 NMS 的排序键是 score × area不是纯 score偏好「又准又大」的脸有利于丢掉碎小重复框。7. 坐标系叠层最易踩的坑一张脸可能经历多层变换原图→可选全图 downscale记录 sc→可选人体 ROI 裁切原点 (rx,ry)→ 网络输出→ × inv_scale 回到 pad 前图→ (rx,ry) 回到 downscale 图或原图→ × (1/sc) 回到原图图人脸框与五点必须共用同一套逆变换少加一次 ROI 原点或漏除 downscale点会漂出五官。在全图路径上downscale 与 tile ROI 原点都要与五点同步回加。调试口诀在送进 SCRFD 的那张图上画框点 → 已偏解码/pad该图对、拼回原图偏 → ROI 或 downscale框对点飘 → 只修了 box 忘了 kps。8. 关键点质量门禁检测出口就该做送去对齐前建议丢掉分数过低且面积过小两眼距离 ≈0 或左右交叉五点大量落在脸框外明显贴 ROI 边的半张脸除非业务强制半脸尝试。目测正脸时两眼连线近似水平鼻尖在两眼中点偏下嘴角大致对称且间距小于眼距五点整体落在框内。侧脸大角度、口罩、墨镜、手遮嘴框可能仍在点不可信——应让上层降权而不是硬对齐。9. 多人脸消歧谁才是这具身体上的脸一个人体 ROI 内可能出现主人脸、邻人探入、海报、镜面。启发式选分数最高且面积合理者中心更靠人体框 上半部排除中心落在下半身者已有轨迹时选靠近预测脸位者面积异常大且贴边 → 警惕海报。人脸与人体轨迹匹配脸心在人体框内且 IoU 最大阈值约 0.05。消歧错了对齐和识别会非常自信地错——比检不出更难查。10. 姿态、遮挡与分数情况框关键点建议小角度侧脸通常在对侧略偏可识别看相似度大侧脸/后脑可能在不可信丢弃等正脸手遮嘴在嘴角乱可跟识别慎用口罩在嘴失效降期望墨镜在眼不稳双风险低头看手机偏小点挤一团等抬头11. Batch ROI性能与正确性优先动态 batch多人 ROI 一次 Run。注意每张 ROI 的检测缩放 / pad 信息必须分条保存空或过小 ROI 不要占位batch 失败时有串行回退GPU 路径失败可能直接告警返回。批处理是性能优化不是正确性来源先保证单 ROI 框点正确再拼 batch。12. 轻量回退 YuNet加载时若 SCRFD 权重不可用可走 YuNet输入 320。回退精度通常较差但输出契约仍是框点分。必须确认关键点索引与 SCRFD 一致否则对齐模板错位。13. 完整几何例子人体框 → 全图五点人体框(800,200)-(1000,700)即200×500。clamp 后作为 ROI原点(800,200)。ROI 内 SCRFD经左上 pad得到相对 ROIface box: (40, 30, 60, 70)kps[0] 左眼: (55, 48)回到全图box → (840, 230, 60, 70)左眼 → (855, 248)若此前全图曾 ×0.5 downscale还要再 ×2。少一步鼻尖会落到脸颊外Umeyama 残差爆炸。14. 时序让脸别抖单帧框点有噪声。对同一 track短窗指数平滑脸框五点平滑时防止左右眼交叉——可先平滑框再约束点遮挡刚结束几帧降低平滑让新观测快速纠正。平滑改善的是识别分数的时间稳定性不是 mAP。15. 白天/夜间阈值时段分数分布建议白天清晰真脸偏高海报也不低阈可略高靠 ROI/过大脸过滤挡海报夜间低照真脸整体下移略降阈同时提高最小脸边长原则阈值服务「可识别的脸」不是理论最大召回。16. 与对齐模块的交接契约检测交给对齐的最小字段原图像素系脸框原图像素系五点含顺序说明检测分数可选短边、粗姿态两眼距/脸宽。对齐侧不应猜测「是否 mirror」契约稳定联调成本下降一个数量级。17. 常见问题清单现象可能原因有人无脸ROI 过紧切额、阈过高、侧脸、未 tile 补检脸框抖单帧噪声需平滑/跟踪对齐扭曲点序与 kRef5 不一致海报脸无人体附着或过大脸过滤过松框对点在框外只逆变换了 box全往右下偏误用居中 letterbox邻人脸当主人ROI 过大或消歧弱远人无脸全图未 tileROI 太小未放大18. 参数直觉表参数过严过松face_score_thresh漏侧脸/远脸虚影、海报增多max_face_short_ratio放弃近景大脸海报进对齐tile NMS 0.45—过低误伤贴脸两人最小 ROI 32丢远人噪声 ROI19. 为何五点比框「更值钱」同样侧脸框与分数可能仍好看但点落在脸颊时相似变换会把五官拧到怪位置embedding 漂相似度断崖。工程质量应双线检测召回有没有框关键点质量点是否在五官上可视化抽检。只盯检测 mAP、不看点会出现「检测指标好看、识别却不稳」的假象。