帮朋友剪一段行车记录仪素材,画面拼了四个路段的车牌。第一个版本导出后,车主私信说正面车牌没打码。我查了遮罩图层,检测模型确实在那个帧上跑了回结果,但置信度只有0.31------低于我们内部设定的过滤阈值0.45,这个框直接被丢弃了。
这个问题出现在车牌检测的下游过滤环节。我们用微调过的YOLO做车牌检测,输出N个候选框,每个带一个置信度分数和类别标签。原始管线直接按置信度阈值截断,高阈值的优点是漏检少,代价是误检框混入时无法区分轻重。
改动思路是把低置信度框交给后处理:对同一目标的多条重叠预测做IoU计算,保留得分最高的一条;连续N帧都没有检测到的区域,不急于清空状态而是给一个衰减系数。实测把阈值降到0.35、配合重叠框合并逻辑后,侧拍角度车牌的覆盖率提升了。
第二个问题更隐蔽:人脸遮罩活过转场。
素材从一个场景切到另一个场景(硬切),人物离开画幅后镜头对准了空场景。导出的成片里,上一段人物的遮罩还盖在新画面上大约1.3秒。排查发现不是渲染问题------是转场检测逻辑根本没触发。
我们有三路信号判断转场:灰度直方图差异、HSV颜色差异、帧差值。阈值分别是0.40、0.72、0.33(这些数字来自对一批含转场素材的实测分布)。但真实切点上的三个值分别是0.173/0.304和0.284,全部低于阈值,导致硬切判定失败。
追踪器在丢帧后的做法是外推:连续MAX_MISSED=20步(约12fps下1.33秒)用卡尔曼过滤推算下一帧位置,alpha系数从1线性降到0.5就停。修法是在不改动硬切判据(误判空白的代价比漏检更大)的前提下,新增一条「要不要继续外推」的软判决:多路信号投票、阈值降到大约原来的三分之一,同时禁止外推到另一段素材。
第三个问题是追踪器重启后的ID撞号。硬切时我们重置tracking系统,track ID从1重新开始编号。而轨迹过期的处理方式是从活跃列表里删除、但保留到后处理阶段的新对象中。新的一段素材第一帧检测到的目标拿到了tid=1,赋值操作把老素材里的tid=1的整段数据覆写了。
实测一条被追踪4.6秒、76帧真实检测的脸,最终遮罩一段都没输出。(排查靠的是在每帧追踪后dump轨迹ID,发现新旧轨的ID对不上。)
修复策略不是合并------下游按时间做二分插值,要求每个key对应单调的一条连续序列。改成「安置」:被顶下来的老轨换个不会被分配到的新key继续存活。这样虽然多占了一小块内存,但保证了轨迹数据的完整性。
这些问题的共同点是:追踪系统的边界条件容易被忽视。检测模型给出的是逐帧的离散结果,追踪器负责把它们连成连续的时间线。任何一端的异常处理不完整------置信度过滤太激进、转场信号阈值偏高、ID复用策略不当------都会在成片时表现为偶发的隐私数据泄露。
测试时需要用真实素材跑全片抽样帧验证,而不是只做单帧的单元测试。推荐的做法是用ffmpeg的select=gt(scene,0.2)独立核对真实的切点位置,和追踪系统的判定结果做交叉验证。
本文来自抹影的开发笔记。