JA EN ZH

光流基础与视频分析 - 运动估计原理到实现

· 9 分钟阅读

什么是光流 - 图像间的运动向量场

光流 (Optical Flow) 是描述图像序列中像素表观运动的 2D 向量场。对于每个像素,光流向量 (u, v) 表示该像素从一帧到下一帧的水平和垂直位移。

基本假设:

  • 亮度恒常性: 物体移动时像素亮度不变。I(x,y,t) = I(x+u, y+v, t+1)
  • 小位移: 帧间运动足够小,可用一阶泰勒展开近似

光流约束方程: 对亮度恒常性假设进行泰勒展开得到: Ix×u + Iy×v + It = 0,其中 Ix、Iy 是空间梯度,It 是时间梯度。一个方程两个未知数 (u,v),这就是著名的孔径问题 (Aperture Problem)。

稀疏光流 vs 稠密光流:

  • 稀疏光流: 仅计算特征点 (角点) 的运动。速度快,适合目标跟踪
  • 稠密光流: 计算每个像素的运动。信息完整,适合视频分析

应用领域: 视频稳定、动作识别、自动驾驶、视频插帧、运动分割、视频压缩 (MPEG 运动补偿)。

经典方法 - Lucas-Kanade 和 Horn-Schunck

两种经典光流方法通过不同的额外约束解决孔径问题,各有优缺点。

Lucas-Kanade (1981):

  • 假设局部窗口 (如 15×15) 内所有像素具有相同运动
  • 在窗口内建立超定方程组,最小二乘求解
  • 稀疏光流方法,通常在角点处计算
  • 金字塔 LK: 多尺度处理大位移。从粗到细逐级精修
  • OpenCV: cv2.calcOpticalFlowPyrLK(prev, next, points, None)

Horn-Schunck (1981):

  • 全局方法,假设光流场整体平滑
  • 最小化: 数据项 (亮度恒常性) + 平滑项 (光流梯度)
  • 通过迭代求解产生稠密光流
  • 平滑权重 α 控制平滑程度: α 大则光流平滑但细节丢失

Farneback 方法 (2003): 使用多项式展开近似每个像素邻域,计算稠密光流。OpenCV 默认的稠密光流方法: cv2.calcOpticalFlowFarneback(prev, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)。速度和精度的良好平衡。

深度学习光流 - 从 FlowNet 到 RAFT

深度学习方法通过端到端训练大幅超越经典方法的精度,尤其在大位移和遮挡区域。

FlowNet (2015): 首个端到端光流 CNN。FlowNetS (单流) 和 FlowNetC (相关层) 两种架构。在合成数据 (Flying Chairs) 上训练。开创了学习光流的先河。

PWC-Net (2018): 金字塔、变形、代价体积的组合。多尺度特征金字塔,逐级变形和精修。参数量小 (8.75M),速度快。

RAFT (2020): 当前最先进的光流方法之一:

  • 构建全对相关体积 (4D): 计算所有像素对的相似度
  • GRU 迭代更新: 从初始零流开始,迭代精修光流估计
  • 多尺度相关查找: 在不同分辨率的相关体积中查找
  • Sintel 基准 EPE: 1.43 (clean), 2.71 (final)

最新进展:

  • FlowFormer (2022): Transformer 编码代价体积,捕获全局上下文
  • VideoFlow (2023): 利用多帧信息提升时间一致性
  • UniMatch: 统一光流、立体匹配和深度估计的框架

光流应用 - 动作识别到视频编辑

光流作为视频理解的基础表示,在多个领域有广泛应用。

动作识别: 双流网络 (Two-Stream) 将 RGB 帧和光流作为两个输入流,融合空间和时间信息。光流流捕获运动模式,对动作分类贡献显著。TVL1 光流是常用的预计算方法。

视频插帧: 利用前后帧的光流,在中间时刻合成新帧。双向光流 + 变形 + 融合是标准流程。RIFE、IFRNet 等方法可实时将 30fps 视频转为 60/120fps。

视频稳定: 估计帧间全局运动 (仿射变换或单应性),补偿相机抖动。区分前景运动和相机运动是关键。

运动分割: 利用光流将独立运动的物体从背景中分离。光流幅度和方向的不连续性指示物体边界。

视频编辑:

  • 光流引导的风格迁移: 保持时间一致性
  • 视频修复: 利用光流从相邻帧传播信息填充缺失区域
  • 慢动作生成: 光流插帧实现时间超分辨率

光流可视化与评估指标

光流的可视化和定量评估对于算法开发和调试至关重要。

颜色编码可视化: 标准方法使用 HSV 色轮: 色相 (H) 表示运动方向,饱和度 (S) 表示运动幅度。Middlebury 色轮是最常用的编码方案。OpenCV 实现: 将光流转换为极坐标 (幅度, 角度),映射到 HSV,再转 BGR 显示。

箭头可视化: 在图像上绘制运动向量箭头。适合稀疏光流或下采样后的稠密光流。箭头长度和方向直观表示运动。

评估指标:

  • EPE (End-Point Error): 预测光流与真实光流的欧氏距离平均值。主要指标
  • Fl-all: 误差超过 3 像素且超过 5% 的像素比例 (KITTI 指标)
  • AE (Angular Error): 预测和真实光流向量的角度差

基准数据集:

  • Sintel: 动画电影渲染的合成数据,有 clean 和 final (含运动模糊、雾) 两个版本
  • KITTI: 真实驾驶场景,LiDAR 提供稀疏真值
  • Flying Chairs/Things: 大规模合成训练数据

实现指南 - 使用 OpenCV 和 RAFT 进行运动估计

从 OpenCV 经典方法到 RAFT 深度学习方法的具体实现代码和部署指南。

OpenCV 稀疏光流 (Lucas-Kanade):

prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
points = cv2.goodFeaturesToTrack(prev_gray, 100, 0.3, 7)
new_points, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, next_gray, points, None)

OpenCV 稠密光流 (Farneback):

flow = cv2.calcOpticalFlowFarneback(prev_gray, next_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
# flow.shape = (H, W, 2), flow[...,0]=水平, flow[...,1]=垂直

RAFT 部署:

  • 安装: pip install torch torchvision,克隆 RAFT 仓库
  • 预训练模型: raft-things.pth (通用), raft-sintel.pth (动画风格)
  • 推理: 输入两帧 RGB 图像,输出稠密光流场
  • GPU 推理速度: 1080p 约 100-200ms (RTX 3090)

实时光流技巧: 降低输入分辨率 (1/2 或 1/4) 可大幅提速; 使用 RAFT-Small 变体; TensorRT 优化可提速 2-3 倍。对于实时应用,Farneback 在 CPU 上仍是实用选择。

Related Articles

特征点匹配基础 - SIFT、ORB 和 AKAZE 的原理与实现

系统讲解图像特征点匹配技术。涵盖 SIFT、ORB、AKAZE 的原理,以及 BFMatcher、FLANN 匹配和 RANSAC 几何验证。

图像插值方法对比 - 最近邻、双线性、双三次和 Lanczos

系统对比图像缩放中的插值算法。涵盖最近邻、双线性、双三次和 Lanczos 的原理、质量和性能差异。

Alpha 抠图技术详解 - 从自然图像中实现精确前景提取

全面解析 Alpha 抠图技术,从三值图输入设计到闭式抠图、深度学习抠图方法。涵盖头发丝级别的精确前景提取原理与实践工作流程。

背景去除技术详解 - 分割与抠图处理的工作原理

详解图像背景去除(背景透明化)所使用的技术。比较语义分割、基于三值图的 Alpha 抠图和边缘检测方法的原理与精度差异。

立体视觉与距离测量 - 从视差恢复 3D 信息

详解立体视觉的原理,从对极几何到立体匹配算法 (SGM、深度学习),涵盖视差图到 3D 点云的转换和实际系统搭建。

单目深度估计技术与应用 - 从单张图像推断深度

从 MiDaS 和 DPT 模型到自动驾驶和 AR 应用的深度图生成系统指南。涵盖原理到实际实现。

Related Terms