畅联云平台丨10-主角锁定与focus决策

主角锁定与 focus 决策:从底图相似度到跟拍开关
本文讲透一件事:检测与跟踪给出的是「一堆带 track_id 的人」,成片却要回答「谁是用户本人、要不要开镜头、要不要糊路人」。本项目把答案落在两层:先按底图相似度锁定 hero_byte_track_id,再按是否单人/双人、峰值人数等做 focus 决策。
一、问题定义:跟踪不等于认人
ByteTrack 只保证「前后帧尽量是同一个人」,不保证「这个人就是上传底图的那个人」。
没有主角锁定时会出现:
- 镜头跟了路人;
- 路人虚化误伤本人;
- 双人合影时推镜头却推到背景。
交付物必须是:一个稳定的主角轨迹号,以及基于它的效果开关。

图:底图 embedding → 各轨迹逐帧相似度 → 按 track_id 聚合 → 选出 hero。
二、底图如何变成可比向量
用户提供一张本人照片(thumb)。流程:
- 在底图上检出脸(必要时再检测或整图兜底);
- 对齐到 112×112;
- ArcFace 得到 embedding,并做 L2 归一化。
之后视频里每一张候选脸,也走同一套对齐与 embedding,再与底图做余弦相似度。业务硬门常用:
相似度阈值 = 0.32
低于该门的单次观测,一般不参与「像主角」的硬判定;轨迹级聚合还会看均值、最大值、高分占比。
三、观测如何挂到轨迹上
扫描阶段,每隔 detect_stride 帧做一次人体检测与跟踪更新。对活跃轨迹:
- 取该轨迹当前人体框;
- 在人体 ROI 内检脸;
- 有底图时,对 ROI 内各脸算相似度,取最高者作为本帧观测;
- 写入该 track_id 的历史:脸框、人体框、sim。
没有底图时,无法用相似度认人,只能退化为「出现次数最多 / 最显眼」一类 启发式——产品上通常要求上传底图。
四、 轨迹级打分:不只看单帧最高分
单帧相似度会抖:侧脸、遮挡、曝光 都会让某一帧掉到 0.2 以下,下一帧又回到 0.5。锁定应按轨迹统计,而不是「随便哪一帧过了 0.32 就锁死」。
本项目对每条轨迹维护大致如下统计:

综合分直觉:
thumb_core ≈ 0.12×均值 + 0.58×最大值 + 0.30×高分占比
再乘上「画面显著性」:
prominence ≈ 0.55×相对面积 + 0.45×靠近画面中心
最终:
score ≈ 0.72×thumb_core + 0.28×prominence

图:相似度核心与画面显著性加权;远处偶发高分路人不易压过近景本人。
数值例子
轨迹 A:均值 0.41,最大 0.55,高分占比 0.7,prominence 0.8
thumb_core ≈ 0.12×0.41 + 0.58×0.55 + 0.30×0.7 ≈ 0.56
score ≈ 0.72×0.56 + 0.28×0.8 ≈ 0.63
轨迹 B:某一帧闪到 0.50,但均值 0.22、高分占比 0.1、人在角落 prominence 0.2 → 综合分远低于 A,不会抢走主角。
硬门仍在:若均值与最大值都低于 0.32,该轨迹直接判不合格。
五、何时写下 hero_byte_track_id
在线锁定逻辑(有底图时)大致两档:
- 优先选「平均相似度 ≥ 0.32」且均值最高的轨迹;
- 若没有,再选「历史最大相似度 ≥ 0.32」且最大分最高的轨迹。
锁上之后:
- 记录锁定帧、锁定脸框;
- 后续跟拍点列、路人排除都认这个 track_id;
- 同 ID 短暂丢检时,靠跟踪缓冲续命,而不是立刻换人。
if (avg >= 0.32f && (!found || avg > best_avg)) {
found = true;
best_avg = avg;
best_id = track_id;
}
// 若仍未找到:再按 max_sim >= 0.32 兜底无底图时:退化为选「有效观测次数最多」的轨迹,并把确认相似度记为 0——这只是工程兜底,不是可靠认人。
六、锁定失败长什么样
典型失败:

调试时优先看:底图 embedding 是否有效、各轨迹的 avg/max/n/hi、锁定帧的脸是否贴住本人。
七、 focus 决策:锁定之后开什么效果
锁定只回答「谁」。成片还要回答「怎么拍」。本项目在单片处理时,用一组布尔量刻画场景:


图:先看是否有 hero,再分单人/双人,最后叠加设备开关与人数门槛。
决策直觉:
- 没锁定主角 → 通常不做跟拍/糊路人(避免跟错);
- 单人主角 → 适合 lens/crop/push-in,不必糊人;
- 双人(主角+路人)→ 可跟拍主角,并按开关启动椭圆虚化;
- focus_eligible 还要求「够多人/够显眼」才开聚焦,避免空镜乱推镜头。
设备侧还可独立配置:跟拍模式(lens/crop)、是否 push-in、是否允许路人虚化、虚化半径等。决策日志里会打出 peakCount、hasHero、duoScene、heroTrackId、thumbBestSim,便于复盘「为什么这片没开 focus」。
八、与下游模块的契约
锁定成功后,下游只应消费「已确认的主角轨迹」:
- 跟拍:从 hero 的脸/人体历史生成平滑中心点列;
- 路人虚化:凡 track_id 等于 hero,或相似度/IoU 像主角的观测,一律排除;
- 质量分里的「人物项」:常以是否锁定且相似度够门为满分条件之一。
契约破坏的症状很典型:圆镜跟路人、本人被糊、双人片却按单人推进。排查顺序应是:底图 → 轨迹 sim 统计 → hero_id → 决策布尔量,而不是先怀疑编码器。
九、参数与失败模式

常见故障:
- 底图多人脸却未指定主脸 → embedding 可能不是用户;
- 只信单帧 max_sim → 路人侧脸偶然像,抢锁;
- 锁定过晚 → 片头数秒无轨迹点,跟拍起步空窗;
- ID switch 后仍死守旧 ID → 镜头停在空气里。
