2. 多帧合成原理:包围曝光、对齐、权重与融合

各位同学,欢迎来到第二章。上一章我们聊了HDR的基本概念,知道了单帧的局限性。那多帧合成到底是怎么工作的?说白了,就是把几张欠曝、正常、过曝的照片,挑各自最好的部分,拼成一张完美的图。

这个过程,我习惯把它拆成四个核心步骤:包围曝光拍摄 → 多帧对齐 → 权重计算 → 最终融合。每一步都有坑,咱们一个一个来拆。

核心观点:多帧合成不是简单的“亮部取暗帧、暗部取亮帧”,而是基于像素置信度的加权平均。权重决定了最终画质的上限。

多帧合成核心流程 包围曝光 3~7帧 不同EV 多帧对齐 特征匹配/光流 权重计算 曝光度/对比度/饱和度 融合输出 加权平均 + 色调映射 ⚠️ 关键约束 • 包围曝光:EV步长通常为1.0或2.0,步长越大动态范围越宽,但对齐难度增加 • 对齐精度:亚像素级对齐是消除鬼影的前提,1/2像素误差就会产生可见重影 • 权重设计:避免硬阈值切换,使用平滑过渡的权重函数

2.1 包围曝光原理

包围曝光,英文叫Bracketing。就是相机固定在三脚架上(或者手持连拍),以不同的曝光值连续拍几张。我一般拍3到5张,EV步长设1.0或2.0。

举个例子,你拍一个窗边的场景:

  • 欠曝帧(-2EV):窗外天空细节保留,但室内一片死黑
  • 正常帧(0EV):室内中间调还行,但窗外过曝,暗部欠曝
  • 过曝帧(+2EV):室内暗部细节全出来了,但窗外一片死白

这三张单独看都不完美,但合在一起,就能得到一张从阴影到高光都有细节的照片。

我的经验:手持拍摄时,我建议用连拍模式+自动包围曝光(AEB)。快门速度尽量快,避免手抖导致帧间位移过大。如果光线暗,宁可提高ISO也不要放慢快门——后期降噪比对齐重影好处理得多。

2.2 多帧对齐基础

包围曝光拍完了,问题来了:这几张照片不是完全重合的。手持拍摄有抖动,即使三脚架也可能有微风吹动树叶。所以,对齐是必须的。

对齐算法我分两类:

对齐方法 原理 适用场景 精度
全局仿射变换 计算整体平移+旋转 三脚架、静态场景 像素级
光流法 逐像素运动估计 手持、有运动物体 亚像素级
特征匹配+单应性 SIFT/ORB特征点+透视变换 大视角变化 亚像素级

我个人习惯用分层光流。先降采样到低分辨率做粗对齐,再逐层上采样精修。这样既快又准。

我曾经踩过的坑:有一次拍夜景,用了全局仿射对齐。结果路灯下的树叶在晃动,对齐后出现了明显的鬼影——树叶在两张图里位置不同,融合后像幽灵一样半透明。从那以后,我只要场景里有动态元素,就一定用光流法做局部对齐。

2.3 合成权重计算

对齐完了,接下来就是决定每张图的每个像素该占多少比重。权重计算是HDR合成的灵魂。

常用的权重因子有三个:

  1. 曝光度权重:像素值越接近中间调(0.5左右),权重越高。远离中间调(接近0或1)的像素权重低,因为这些区域容易过曝或欠曝,信噪比差。
  2. 对比度权重:局部梯度大的像素权重高。梯度大意味着纹理丰富,细节多。
  3. 饱和度权重:色彩饱和度高的像素权重高。避免融合后颜色发灰。

最终的权重通常是这三个的乘积:

// 伪代码:权重计算
float weight_exposure = exp(-4.0 * pow(pixel - 0.5, 2));
float weight_contrast  = local_gradient(pixel);
float weight_saturation = color_saturation(pixel);
float final_weight = weight_exposure * weight_contrast * weight_saturation;

你想想看,为什么要用乘积而不是加法?因为任何一个权重为0,这个像素就不该被信任。比如一个像素过曝了(曝光度权重接近0),即使它纹理丰富(对比度高),也不该用它。

关键点:权重函数必须是平滑的,不能有硬阈值。硬阈值会导致融合后出现明显的接缝或带状伪影。我常用高斯型权重函数,过渡自然。

2.4 最终融合策略

权重算好了,最后一步就是融合。说白了,就是加权平均:

// 伪代码:多帧融合
float3 hdr_pixel = float3(0, 0, 0);
float total_weight = 0;

for each frame i:
    float w = weight_map[i][x][y];
    hdr_pixel += w * frame[i][x][y];
    total_weight += w;

hdr_pixel /= total_weight;

但这里有个细节:融合是在线性空间做的,不是在sRGB空间。因为人眼对亮度的感知是非线性的,但物理上的加法运算必须在线性空间才正确。所以流程是:

  • 将sRGB图像反Gamma校正到线性空间
  • 在线性空间做加权平均
  • 再Gamma校正回sRGB输出

嗯,这一步很多人会忽略,结果融合出来的HDR图像颜色怪怪的,对比度也不对。

我的建议:融合完成后,别忘了做一次全局色调映射(Tone Mapping)。因为加权平均后的HDR图像动态范围可能超过显示器的能力,需要压缩到0~1之间。常用的方法有Reinhard、Filmic、ACES等。我项目里用ACES最多,色彩还原最准。

2.5 本章小结

多帧合成的四个步骤,环环相扣:

  • 包围曝光决定了输入数据的质量,EV步长和帧数要权衡
  • 多帧对齐是消除鬼影的基础,光流法比全局变换更鲁棒
  • 权重计算决定了融合的智能程度,曝光度+对比度+饱和度三管齐下
  • 最终融合要在线性空间做加权平均,别忘了色调映射