系列编排日期为 2026 年 8 月;正文依据 2026-10-12 核对的实现整理。历史实测保留真实日期,教学数字不代表实测;本次未重新执行板端推理。
返回系列目录 · 本篇为 14 章+4 份附录中的一篇。
分割回答的是可见脸部像素
本项目使用 FaceExtraction 的原始 FaceOcc 权重:ResNet18 编码器的 U-Net,输入 RGB/255,输出单通道 logits。方法及原始权重入口见 FaceExtraction 官方仓库。这里不将其他同名再训练版本的参数或预处理替换进来。
U-Net 通过编码器提取上下文,通过解码器与跨层特征连接恢复空间细节。当前只有一个输出通道,因此没有独立的鼻、嘴、手、口罩类别。鼻嘴位置来自 PIPNet,不能从 FaceOcc 输出直接读取。
logits、概率、覆盖率是三个量
|
当前 mask_threshold=0.5,所以像素二值判定等价于 logit≥0。实际代码仍计算概率,以便输出平均值和预览。为避免指数溢出,策略计算将 logits 限制在 −80 到 80。
假设一个 ROI 有 100 个像素,其中 60 个概率 0.51,40 个概率 0.01:覆盖率为 60%,平均概率为 0.31。覆盖率达到默认阈值,但 meanP 明显低于 0.5。这并不矛盾,两个指标回答不同问题。
鼻嘴区域怎样建立
- 鼻部取 51~59,嘴部取外唇 76~87。
- 归一化坐标乘 256;任一点落在 0~255 外就拒绝这个区域。
- 用
nearbyint取整,计算凸包。 - 凸包连续面积不足 4 平方像素,判为退化。
- 填充凸包得到二值 mask;默认用半径参数 2 的 5×5 椭圆核膨胀。
- 膨胀后像素数少于 16,或碰到任意图像边缘,判为过小或被裁切。
- 仅对有效 mask 计算覆盖率和平均概率。
面积 4 与像素数 16 是不同检查:一个基于几何多边形面积,一个基于栅格 mask 计数。不能将两者合并成“ROI 至少 16 平方像素”后删除几何退化检查。
padding 的目的与代价
外扩让统计包含关键点连线附近的像素,减少轮廓过窄造成的采样不稳定。但 ROI 变大之后,可能包含更多皮肤,也可能包含更多背景,因此覆盖率变化不保证单调。外扩也可能让原本有效的区域触边并变为无效。
roi_padding=2 的单位是 256 输入上的像素。一个原图宽 128 像素的脸部裁剪,2 个网络像素约等于 1 个原图横向像素;原裁剪宽 512 时则约等于 4 个。直接在原图固定膨胀 2 像素会改变算法。
逐点 Upts 为什么不是面积覆盖率
当前板端逐点诊断在每个点周围取半径 2 的离散圆,共 13 个像素,统计可见比例。点距离边缘不足以容纳完整圆时,不采样;最后仅对有效点的比例求均值。
鼻部逐点统计 9 点,嘴部统计 20 点,而嘴部面积 ROI 使用 12 个外唇点。两个分母也不同:一个按采样点平均,一个按 ROI 面积计数。
代码将半径固定为 2,并在 JSON 输出 radius_pixels_256=2;当前可序列化的 FacePolicyConfig 没有对应半径参数。即使旧界面说明提到“采样半径”,也不能假定现在支持任意调整。
哪些情况会出现低覆盖
手、口罩、纸巾可能减少可见脸部像素;张嘴造成的口腔区域、胡须、强阴影、侧面、自遮挡和域外输入也可能造成低覆盖。嘴部凸包包括外唇围成的口腔区域,所以不能把“张嘴”和“手遮嘴”的绿色减少视为同一证据。
分割也可能把手误判成脸,或者关键点漂到脸颊的可见皮肤上,使覆盖率虚高。后者是当前可见优先策略最需要验证的路径:PIPNet 定位与 FaceOcc 采样并不独立,分割统计依赖关键点选出的区域。
分割显示与判定边界
正常情况下绿色只是可见脸部可视化。有效鼻嘴 ROI 各达到默认 60% 时才形成当前规则的放行;不是整张图 60% 绿色,也不是整个脸框 60% 绿色。
某个鼻嘴区域无效时,不能把其覆盖率填成零。零是“区域可统计,但没有可见像素”,无效是“无法可靠定义统计分母”。JSON 应保留 valid=false 与具体 reason,界面显示 N/A 或破折号。
转换验证该比较什么
固定裁剪后比较 logits 的误差、二值 mask IoU、像素分类不一致比例,以及鼻嘴覆盖率和状态是否变化。掩膜 IoU 很高也可能恰好在鼻嘴边缘产生差异,导致跨过 60% 阈值,因此必须检查局部区域。
2026-09-17 的独立 FaceOcc 记录使用少量样本验证转换一致性,不是标注准确率;其侧脸样本相对 PC 的 mask IoU 约 94.33%,不能据此宣称侧脸检测准确率为 94.33%。
核对入口:FaceOcclusionPolicy.cpp::region() 与 evaluateFace();原始权重说明及资源记录在 unet_occlusion/。
