多帧融合原理:从曝光序列到鬼影消除
多帧融合,说白了就是把不同曝光量的几张照片合成一张。你想想看,单帧的动态范围撑死了也就 60-70dB,但人眼能感知 120dB 以上。怎么办?拍多张,然后融合。
我刚开始做 HDR 时,以为就是简单加权平均。结果第一次测试就翻车了——运动物体拖影严重,鬼影满天飞。嗯,这里面的坑,咱们一个一个填。
2.1 多帧曝光序列
多帧融合的第一步,是拿到一组曝光不同的图像序列。通常我们用三种策略:
| 策略 | 典型帧数 | 曝光步长 | 适用场景 |
|---|---|---|---|
| 对称式 | 3 帧(-2EV, 0EV, +2EV) | 2EV | 静态场景,快速出图 |
| 非对称式 | 5 帧(-3EV, -1.5EV, 0EV, +1.5EV, +3EV) | 1.5EV | 高动态场景,暗部细节优先 |
| 自适应式 | 动态帧数 | 根据直方图实时调整 | 复杂光照,专业模式 |
曝光序列的采集顺序也很关键。我个人习惯按「中-短-长」的顺序拍。为什么?因为中间帧作为参考帧,先拍可以保证对齐的基准质量。短帧次之,长帧最后——长帧最容易出现运动模糊,放在最后可以用短帧来修正。
2.2 帧对齐技术
拿到多帧图像后,第一件事就是对位。手持拍摄不可能完全静止,哪怕三脚架也会因为风吹而微动。帧对齐的核心就是找到帧间的几何变换关系。
常用的对齐模型分三种:
- 平移模型(2 参数):只处理 x/y 方向位移。适合三脚架场景,计算量最小。
- 仿射模型(6 参数):处理平移+旋转+缩放。手持拍摄最常见,我大部分项目都用这个。
- 透视模型(8 参数):处理更复杂的形变。适合有透视变化的场景,但容易过拟合。
对齐的算法流程,我一般这样走:
- 特征提取:用 FAST 或 Shi-Tomasi 角点检测,提取参考帧和待对齐帧的特征点。
- 特征匹配:用光流法或块匹配(Block Matching)找到对应点对。
- 变换估计:用 RANSAC 剔除误匹配,求解变换矩阵。
- 图像重采样:用双线性插值或双三次插值,将待对齐帧变换到参考帧坐标系。
关键指标: 对齐精度通常用 PSNR 或 SSIM 衡量。我要求对齐后的帧间 PSNR 不低于 35dB,否则融合后会出现重影。低于 30dB 时,必须启用运动补偿。
2.3 运动补偿
对齐只能解决全局运动(相机抖动),解决不了局部运动(行人、车辆、树叶晃动)。这时候就需要运动补偿。
运动补偿的思路是:把图像分成小块(比如 16x16 或 32x32),对每个块单独做运动估计和补偿。
我常用的方法:
- 块匹配(Block Matching):在参考帧的搜索窗口内,找当前块的最佳匹配位置。用 SAD(差和)或 SSD(平方差和)作为匹配代价。
- 光流法(Optical Flow):用 Lucas-Kanade 或 Farneback 算法,计算每个像素的运动矢量。精度高,但计算量大。
- 分层运动估计:先降采样图像,在低分辨率下做粗估计,再在高分辨率下做细估计。这是我在项目中用的最多的方案,速度快,精度也够。
// 分层运动估计伪代码
function hierarchicalMotionEstimation(ref, target, levels=3):
// 构建图像金字塔
pyr_ref = buildPyramid(ref, levels)
pyr_target = buildPyramid(target, levels)
// 从顶层开始,逐层细化
flow = zeros(2, H/2^levels, W/2^levels)
for l = levels-1 down to 0:
// 上采样光流到当前层
flow = upsample(flow, pyr_ref[l].size)
// 在当前层做光流细化
flow = refineFlow(pyr_ref[l], pyr_target[l], flow)
return flow
2.4 鬼影消除基础
鬼影是 HDR 多帧融合最头疼的问题。即使做了对齐和运动补偿,运动物体在不同曝光帧中的位置仍然不一致,融合后就会出现半透明的「鬼影」。
鬼影消除的基本思路:检测运动区域,然后只从单帧中取该区域的信息。
常用的检测方法:
- 帧差法:计算对齐后帧间的差,超过阈值就认为是运动区域。简单,但阈值不好调。
- 梯度一致性检测:比较帧间的梯度方向。运动区域的梯度方向会突变,这个比帧差法更鲁棒。
- 基于深度学习的检测:用轻量级 CNN 做运动区域分割。精度最高,但需要训练数据和硬件支持。
检测到运动区域后,融合策略要调整:
| 区域类型 | 融合策略 | 说明 |
|---|---|---|
| 静态区域 | 多帧加权融合 | 正常 HDR 融合,权重由曝光质量决定 |
| 运动区域 | 单帧选取 | 只从参考帧或曝光最合适的帧中取像素 |
| 过渡区域 | 渐变融合 | 用羽化或泊松融合做平滑过渡,避免边界突兀 |
2.5 本章知识体系
下面这张图总结了多帧融合的核心流程和关键技术点:
从流程图可以看出,多帧融合是一个串行流水线。每一步的输出质量都会直接影响下一步。我个人在项目中踩过最大的坑就是——帧对齐没做好就急着做鬼影检测,结果运动区域检测全是假阳性。后来我定了个规矩:对齐精度不达标,绝不往下走。
本章核心要点:
- 多帧曝光序列推荐对称式 3 帧(-2EV, 0EV, +2EV),性价比最高
- 帧对齐用仿射模型 + RANSAC,对齐精度要求 PSNR ≥ 35dB
- 运动补偿用分层估计,块大小自适应(8x8 ~ 32x32)
- 鬼影消除的核心是运动区域检测 + 差异化融合策略
- 过渡区域用羽化或泊松融合,避免边界接缝