在视频编辑器中,“光流追踪”很容易被做成满屏箭头:比较前后两帧,计算像素位移,然后把向量绘制到画面上。
这种效果看起来很“技术”,但真正放进产品后会遇到一个问题:背景纹理、字幕、镜头抖动都可能产生大量向量。用户看到的是一片噪声,却不知道画面里的哪一群人、哪个物体正在向什么方向移动。
因此,我们没有把光流追踪简单地理解为“绘制像素位移”,而是把它设计成一个浏览器本地运行的“语义群体运动实验”。
项目地址:https://github.com/MartinDelophy/ai-video-editor
传统光流关注的是相邻帧之间的像素变化。对于视频中的一个采样点,可以得到一个二维运动向量:
v=(Delta x,Delta y)
其中,(Delta x) 表示水平方向位移,(Delta y) 表示垂直方向位移。
把大量向量绘制到视频上,就能形成常见的光流可视化效果。但这些向量并不理解画面内容。
例如:
如果直接根据这些向量进行聚类,很容易把背景纹理误认为一个“运动群体”。
所以我们调整了思路:先回答“画面里的人或物体在哪里”,再回答“这个主体如何移动”。
完整流程被拆分为五个阶段:
视频片段
↓
主体语义检测
↓
生成大块语义区域
↓
区域内部计算局部光流
↓
聚合主体运动并累积轨迹
↓
生成带向量和时间码的结果视频系统首先在锚点帧中寻找人物或主要物体。
浏览器端优先使用轻量级目标检测模型获取候选区域。如果人物检测结果不稳定,则继续使用本地人物分割和已有目标检测能力作为降级方案。
当前策略包括:
这里有一个重要原则:一个清晰的人或物体本身就是一个有效群体,并不要求画面中必须出现多个人。
检测结果不会直接变成很多零散的小区域。
对于距离较近、运动方向一致的人物,可以将其合并为一个较大的运动群体;对于主要物体,则保留其核心语义区域。
每个群体包含:
这样,后续计算关注的是“这个人物群体向左移动”,而不只是“这里有几十个像素向左移动”。
获得语义区域后,系统会对相邻采样帧进行灰度化,并在区域内部执行块匹配。
假设当前块中心为 ((x,y)),系统会在下一帧的局部搜索窗口中寻找差异最小的位置:
E(dx,dy)=frac{1}{N}\sum{i=1}^{N}|I_t(i)-I{t+1}(i+dx,i+dy)|
误差最小的 ((dx,dy)) 就是这个图像块的候选运动向量。
为了减少噪声,还需要继续过滤:
最后,对保留下来的向量进行加权聚合,得到群体主运动:
V_g=frac{sum_i c_i v_i}{sum_i c_i}
其中,(v_i) 是局部向量,(c_i) 是对应的置信度。
单帧光流只能说明“这一刻往哪里移动”,但用户更容易理解一条连续轨迹。
因此,每处理完一帧,系统会使用群体主向量更新群体中心:
Pt=P{t-1}+V_t
同时把新的中心点写入轨迹序列:
track.points.push({
x: nextCenterX,
y: nextCenterY,
time: frameTime
});连续处理后,便可以得到主体从 A 点移动到 B 点的轨迹。
为了让实验结果更直观,画面中同时保留:
相比满屏绘制检测框和标签,这种方式更接近“完成后的科学可视化结果”。
浏览器本地计算必须兼顾性能。
如果直接在 1080P 或 4K 视频上逐帧计算光流,CPU 开销、内存占用和处理时间都会明显增加。因此,我们将分析与成片渲染分成了两条路径。
分析路径:
渲染路径:
也就是说,计算可以使用192像素宽的分析帧,但最终视频不会把这张小图直接放大,而是重新在源视频清晰帧上完成合成。
这个设计解决了早期版本中结果视频明显模糊的问题。
如果光流分析结束后只停留在右侧面板,它仍然只是一个临时预览,无法参与后续编辑。
因此,完成分析后,系统会继续执行:
素材中会保存:
{
type: "video",
generatedBy: "optical-flow-tracking",
duration,
width,
height,
trackFrames,
trackFrameDuration,
diagnostics: {
detector,
sampleRate,
vectors,
cohorts,
dominantAngle,
stability
}
}这样生成的视频可以继续作为主画面或画中画素材使用,也能在时间线中显示真实帧序列,而不是一个空白色块。
整个实验不需要把用户视频上传到服务器。
视频解码、人物或物体识别、光流计算、轨迹聚合和结果编码都在当前浏览器中完成。
这种方式具有几个优势:
当然,浏览器本地处理也有边界。长视频、高采样率和高分辨率会增加计算时间;快速遮挡、镜头切换以及严重运动模糊,也可能导致群体轨迹不稳定。
因此,这项功能目前仍被定位为实验能力,而不是精密的工业测量工具。
我们使用一段分辨率为852×480、时长约2秒的视频进行测试,并将时间采样设置为4fps。
处理结果包含:
分析完成后,浏览器自动生成了一段852×480的光流结果视频,并将其加入“我的素材”。
输出画面保留原始视频清晰度,同时叠加青色向量、群体边界、累计轨迹和右上角时间码。
这次开发中最重要的变化,不是换了一种光流算法,而是改变了光流在产品里的语义。
原来的问题是:
帧与帧之间有哪些像素发生了变化?
现在的问题是:
画面中的人物或物体群体正在如何移动,它的运动轨迹是什么?
通过“语义检测、区域光流、群体聚合、轨迹累计、高分辨率渲染和素材入库”这条完整链路,光流不再只是铺满画面的技术特效,而是成为一种能够被理解、复用和继续编辑的运动分析素材。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。