畅联云平台丨07-Lens与Crop跟拍几何

2026年9月2日
畅联云平台丨07-Lens与Crop跟拍几何

Lens 与 Crop 跟拍几何:从人脸锚点到成片窗口

只讲坐标、公式、数值例子与跟拍几何。


一、两种跟拍各自交付什么

模式 观感 几何本质

二者共用同一套 源坐标轨迹 (cx_src, cy_src)(来自锁定后的人脸/人体锚点),差异在「如何把锚点变成取样窗口」。

图:Lens 用圆心与半径定义取样;zoom 放大后再裁进圆内。



二、镜头几何模块:时间轴上的分段线性

成片时间轴用输出帧号 n(25fps)。轨迹是关键点序列 [(n, value), …]。查询任意 n:

任意帧 n 的值由相邻关键点线性插值得到。

滤镜图里 FFmpeg 表达式 与此同构(分段线性表达式),保证 C++ 预览与成片一致。

关键点抽稀把过密点抽到上限(路人虚化常用 24 点),避免滤镜图爆炸。


三、锚点:脸框如何变成「该跟的点」

扫描得到的是人脸框 (face_x, face_y, face_w, face_h) 与可选人体框。跟拍中心不是随便取框中心:

  • 轨迹用 cy:偏上半身,避免圆心掉到胸口;
  • Lens overlay cy:有人体时锚在人体上部,圆顶高于头顶。

人头保护区(防路人椭圆误伤、也用于几何估计)有硬约束:

由脸估头高:

头高 ≈ 限制在人体高度的 12%~32% 之间(由脸短边×1.38 估计)

数值例子

人体高 800 像素、脸短边 140 时:

头高估计约 193,并限制在人体高的 12%~32% 内。

0.12×800 = 96;0.32×800 = 256。

193.2 落在 [96,256],取 193。若脸异常大(误检),0.32H 会盖帽,避免「头区吞掉半个身子」。


四、Lens:圆镜取样坐标

圆镜叠加原点计算与 FFmpeg 侧圆镜 zoom 叠加坐标一致。成片侧先算:

zoom_x = lens_d / crop_w,zoom_y = lens_d / crop_h

(lens_d = 2 * lens_r),再把放大图层拖到圆窗内。几何核心:

void lens_overlay_src_xy(int lens_r, double cx, double cy,
 double zoom_x, double zoom_y,
 int canvas_w, int canvas_h,
 int &src_x, int &src_y) {
 const int lens_d = lens_r * 2;
 const int ix = (int)std::floor((double)lens_r - cx * zoom_x);
 const int iy = (int)std::floor((double)lens_r - cy * zoom_y);
 const int scaled_w = (int)std::lround((double)canvas_w * zoom_x);
 const int scaled_h = (int)std::lround((double)canvas_h * zoom_y);
 // clamp overlay origin so zoomed layer covers the circular window
 src_x = std::max(lens_d - scaled_w, std::min(0, ix));
 src_y = std::max(lens_d - scaled_h, std::min(0, iy));
}

直觉:

  1. 把源画布按 (zoom_x, zoom_y) 放大;
  2. 希望人物锚点 (cx,cy) 落在圆镜中心;
  3. overlay 偏移把放大图「拖」到正确位置,并 clamp 防止露黑边。

输出侧半径有地板:圆镜半径大约不小于输出短边的 1/6(且至少约 28 像素),避免远景小脸时圆镜缩成豆子。

数值例子(720p 输出)

out=1280×720,lens_r=120,zoom=1.8,锚点源坐标映射后圆心希望在输出 (640,280)

放大后有效图宽 1280×1.8=2304。src_x 大致满足「圆心落在圆窗中心」,

再被 [lens_d - scaled_w, 0] 夹住,保证圆内总能采到像素。


五、 Crop:移动矩形窗

图:源图上 half_w×half_h 的窗以锚点为中心,clamp 进画幅后缩放到输出。


流程:

  1. 收集 lens 有效区间内的 raw 点;
  2. 时间域高斯平滑;
  3. 密采样到 25fps;
  4. 把脸/人装进窗;
  5. 死区 + 速度门控;
  6. 微位移 hold,消灭 1~2 px 残抖。

窗左上角:

裁切窗口左上角:把中心减半宽半高后,夹紧到画面内,避免越界。

clamp 会在人靠近边缘时「顶死」,若不做后处理,轨迹会出现折线拐角——这正是离线平滑与死区要抹平的对象。


六、离线高斯平滑:公式与默认 σ

离线高斯平滑:用邻近关键点按时间距离加权平均,抑制检测抖动。

默认配置:

数值例子

σ=0.72 s @25fps,半高宽时间约 1.7 s,即约 42 帧 的权重仍明显。站立微晃会被抹平;快速横穿会有拖影感——这是有意取舍。

Lens σ=0.12 → 有效约 7 帧,保留更多即时位移。


七、Crop 死区与意图门控

图:死区内冻结;超出 enter 阈值才开始跟随;速度不够则不跟。


死区半径:

d = max(dmin, 脸短边 × 0.45)

滞回:

全片位移若 ≤ d×2.20,直接冻在中心——「人几乎没动就别跟」。

数值例子

脸短边 s=100:

人原地晃 ±30 px:落在死区内,输出中心不变。横移累计 80 px 且速度超过意图阈值:开始以 最大步进 限速追随。


八、Push-in:单人推进变焦

单人素材可走:固定锚点,zoom 从 1 拉到 最大变焦,同时保证主体不离开 crop。

某输出帧 zoom z 时,源窗:

放大倍率为 z 时,窗口宽高约为画面宽高除以 z;再按中心夹紧到画面内。

推进时用主体框与 margin 检查主体是否仍在裁切窗内;若推进会导致出窗则跳过推进,避免「越推越把人脸裁掉」。

数值例子

1080p,z=1.6,锚点 (960,420):

x0=360, y0=82.5

脸若在 y=50 且高 180,顶边可能贴窗;margin≈0.28(f_w,f_h) 会判危险。


九、Lens / Crop 轨迹构建对照

主角轨迹有效帧范围 取 cx/cy 点列的首尾 n,供滤镜 enable='between(n,…)'。


十、源帧号 ↔ 输出 25fps

定位结果带 源帧率(非法则 25)。输出帧:

若源帧率不是 25,先把源帧号换算到 25 帧/秒时间轴再查轨迹。

本项目大量路径直接按 25 处理成片;扫描用源 fps 驱动 ByteTrack 。几何层用 t_sec = frame_idx / fps 做高斯,再用 25fps 密采样写点列——时间在秒域平滑,索引在 25 域交付滤镜。


十一、常见几何故障与心算排查

  1. 圆镜裁头:overlay cy 偏下或头高估计过矮 → 查锚点函数,勿只调 zoom。
  2. 贴边抖:crop clamp 引起 → 看是否绕过了死区/平滑。
  3. 站立仍跟拍晃:死区过小或 σ 过短 → 对照 Crop 默认 0.72 / 0.45。
  4. Lens 与 Crop 选人不同心:是否混用了 face_cy 与 body_cy;Lens overlay 有人体上部锚点加权。

十二、公式卡

分段线性:

v(n)=v0+α(v1-v0), α=(n-t0)/(t1-t0)

高斯:

hat v_i = Σ_j w_ij v_j / Σ_j w_ij,

w_ij = exp(-(t_j-t_i)²/(2σ²))

头高上下限:人体高的 12%~32%。

Crop 死区:

d=max(48, 0.45×脸短边)

Lens 取样偏移(概念):

ix = lens_r - cx·zoom_x,再 clamp 到 [lens_d-scaled_w, 0]

掌握以上,即可从一段 cx_pts/cy_pts 反推成片窗口每一帧的几何来源。


十三、锚点函数对照

本项目里几条函数决定「跟哪一点」与「圆镜采哪一块」:

  • 圆镜轨迹纵向取人脸 / 由人脸框推圆镜 cy:轨迹 cy 偏上;
  • Crop 装人窗锚定(人体框软约束 + 已平滑跟拍点);
  • 圆镜叠加原点计算(见上文代码);
  • 成片跟拍:zoom_x = lens_d / crop_w(及 zoom_y 对称)。

权重含义:轨迹更跟「已平滑的跟拍点」,人体框只做软约束,避免单帧检测框把窗猛拽。

源帧 → 输出 25:做源帧索引映射到 25fps(非法 fps 按 25)。

再算一遍 push-in 锚点

脸 y=200,h=120:

例如:人体框顶在 140、身高 360 时,跟拍中心可取约 140+252=392(偏上半身)。

相对纯脸心 260,锚点下移约 132 px——推进变焦时胸口以上更稳地留在画面里。


十四、Lens 有效窗与尾 hold

离线 Pass 写出圆镜有效截止帧与圆镜结束原因。轨迹点构建止于该帧(含片尾保持秒数,出画原因可几乎为 0)。因此:

  • 扫描期 Kalman 仍可能在后段给出框;
  • 成片圆镜却在有效截止后停用(enable 关掉)。

这是几何层与跟踪层的第二次分工:跟踪尽量不断,镜头有意识结束,避免跟错人或跟到空镜。

美畅美畅物联畅联畅联云平台视频监控云平台云视频监控视频云平台视频开放平台视频感知云视频接入网关AIoT综合接入网关视频中台物联网中台视频上云网关EhomeI连锁行业智慧交通AI算法