站在室内拍向明亮窗外,短曝光能看清云层,室内却接近黑色;长曝光照亮房间,窗户又变成没有纹理的白块。多曝光 HDR 的想法很直接:让不同曝光各自负责最可靠的亮度区间,再把它们恢复到同一个场景尺度。
真正的 HDR Merge 不是把三张 JPEG 调透明度叠起来。曝光时间不同、相机响应可能非线性,暗部噪声和高光饱和的可信度不同;画面里的人和树叶还会在三次拍摄之间移动。
三张曝光不是三个不同场景
在线性传感器的简化模型中:
是场景辐照度, 是第 张曝光时间, 是 RAW 值。只要没有饱和:
三张曝光,各自看见不同区域
短曝光保护高光,长曝光抬起阴影。没有任何一张同时拥有全部可靠信息。
值到达 1.0 后只是白色,无法知道原本是 1.2 还是 12。HDR 合并只能使用未饱和曝光提供的比例。
短曝光中的阴影可能只有几个有效 DN,read noise 占比很高;长曝光中的高光达到 white level 后只剩一个裁剪值。HDR 的信息增益来自不同曝光的可靠区间互补,而不是从已经饱和的数据中恢复纹理。
合并前先回到共同坐标系
RAW 输入至少要处理 BLC、white level 和曝光比例。如果输入是 JPEG 或其他非线性编码,还要知道相机响应函数 :
先应用逆响应 ,才能得到与曝光成比例的量。直接用 sRGB 数字除快门时间不成立,因为 sRGB 不是线性光。
光圈和 ISO 也会改变总曝光。更一般的曝光尺度应来自完整元数据与标定,而不是只看快门分母。模拟增益变化还会改变读出噪声和饱和容量,不能简单假设所有帧噪声相同。
为什么每个样本需要一个权重
一个常见合并式是:
靠近黑位的样本信噪比较差,靠近白位的样本可能饱和,中间值通常更可靠。
为什么最黑和最白的样本权重低
靠近黑位时噪声占比高,靠近白位时容易饱和。权重曲线让中间曝光承担更多估计责任。
权重不是曝光融合的审美蒙版,而是对每个观测可靠性的建模。响应曲线和噪声模型不同,最佳权重也会不同。
三角权重容易解释,Gaussian 更平滑,门限权重则只排除两端。它们都只是启发式基线。若知道传感器噪声方差 ,可以让权重与逆方差相关:
这样“可靠”不再只由编码位置决定,而与 shot/read noise、模拟增益和曝光模式联系起来。
一颗像素怎样合并
把三个编码值还原成一个场景辐照度
先除以曝光时间得到各自估计,再按可靠性加权。饱和曝光会自动失去权重。
示例假定响应线性且没有噪声。JPEG 合并还必须先逆响应曲线;RAW 则要先正确完成 BLC 和曝光归一化。
在组件中提高场景辐照度。长曝光会先饱和,随后中曝光也失去权重,最终只剩短曝光提供高光比例。若所有曝光都饱和,算法只能知道场景至少超过某个下限,无法恢复准确辐照度。
教学版 NumPy 实现:
import numpy as np
def triangular_weight(value): return np.maximum(0.0, 1.0 - 2.0 * np.abs(value - 0.5))
def merge_linear_raw(frames, exposure_times): """frames 已完成 BLC,并按各自 white level 归一化。""" frames = np.asarray(frames, dtype=np.float32) times = np.asarray(exposure_times, dtype=np.float32)[:, None, None] weights = triangular_weight(frames)
estimates = frames / times numerator = np.sum(weights * estimates, axis=0) denominator = np.sum(weights, axis=0) return numerator / np.maximum(denominator, 1e-8)生产实现还要为“所有权重为零”的像素选择最接近未饱和的曝光,并处理坏点、黑位漂移、噪声模型和颜色通道差异。
对齐:同一个场景位置必须落在一起
手持拍摄时,相机在多帧之间平移、旋转,广角镜头和视差还会造成非全局形变。若不先对齐,静态边缘也会出现重影。
全局对齐可以估计单应或仿射变换;更复杂场景需要局部光流、多尺度特征和鲁棒匹配。对齐算法最好在不过曝、纹理足够且噪声可控的表示上工作。直接在亮度差异巨大的编码图上做普通 SSD,容易把曝光变化误认成运动。
运动物体与鬼影
移动物体为什么变成半透明鬼影
不同曝光不是同一时刻。静态背景可以逐像素合并,运动区域必须对齐、选参考帧或拒绝不一致样本。
Deghost 不是简单锐化。它需要区分相机抖动、物体运动、亮度变化与饱和差异,并可能牺牲运动区的动态范围。
背景对齐后,行人、树叶和车辆仍位于不同位置。直接合并会得到多个半透明副本。常见策略包括:
- 选择一张参考帧,运动区域只用它;
- 检测跨帧不一致,拒绝异常观测;
- 使用光流把物体局部对齐;
- 分割运动对象,在可信帧之间选择或重建。
参考帧策略稳定,却会让运动区只保留单帧动态范围。去鬼影本质上是在动态范围、噪声和时间一致性之间取舍。
曝光融合与辐照度 HDR 的区别
曝光融合可以直接根据对比度、饱和度和“曝光良好程度”混合显示图,不一定恢复物理辐照度。它容易得到漂亮结果,但输出通常已是显示映射后的 LDR。
辐照度 HDR 先恢复场景线性值,再交给 Tone Mapping 映射到显示范围。两者都使用多曝光,却回答不同问题。不要把融合输出再当作线性 HDR 交给基于物理亮度的算法。
HDR Merge 与 Tone Mapping 的边界
HDR Merge 解决“不同曝光怎样组成更宽的场景数据”;Tone Mapping 解决“宽范围数据怎样进入有限显示范围”。正确的概念顺序是:
多曝光 RAW → 线性化/对齐/合并 → HDR 场景值 → Tone Mapping → Gamma/OETF如果相机使用单帧双转换增益、交错曝光或分区读出,合并发生得更靠近传感器,但可靠性、饱和和运动问题依然存在。
颜色为什么也会出问题
不同通道的 white level、黑位和噪声可能不同。若某帧红通道饱和而绿蓝未饱和,逐通道独立权重会改变 RGB 比例。高光区域应保留通道饱和 mask,并结合其他曝光恢复颜色。
白平衡增益会改变通道噪声;CCM 是通道混合,通常应在各帧恢复到一致相机线性空间后再统一应用。若每帧使用不同自动参数,合并前必须确认它们的含义一致。
最容易踩的坑
- 把 Gamma 编码 JPEG 当线性值相除;
- 只使用快门时间,忽略光圈、模拟增益和模式变化;
- 把饱和样本当作准确白色参与平均;
- 对齐只看全局变换,忽略近景视差;
- 去鬼影后不记录哪些区域退回单帧;
- 每帧分别做不同 Tone Mapping 后再合并;
- 忽略滚动快门和灯光闪烁造成的帧内亮度差;
- 只在静态三脚架风景上测试。
验证清单
- 已知辐照度和曝光时间的合成序列能否恢复比例;
- 单帧饱和、全部饱和和接近黑位的边界情况;
- 不同噪声强度下权重是否合理;
- 平移、旋转、视差和滚动快门;
- 行人、树叶、流水和屏幕刷新等运动;
- RGB 单通道饱和与中性高光;
- 关闭对齐、去鬼影、噪声权重后的差异是否可诊断;
- 合并结果是否仍为线性 HDR,而不是被隐式裁剪到 。
HDR Merge 的核心不是“多张更亮”,而是把每个曝光还原到同一场景尺度,并在每个位置选择可信证据。曝光归一化回答比例,权重回答可靠性,对齐回答空间对应,去鬼影回答时间不一致;四件事缺一,宽动态范围就可能换来新的伪影。