1501 字
8 分钟
高动态范围成像:多曝光融合与Tone Mapping
2026-06-28
无标签

动态范围的定义在上一篇文章中已经介绍过了。8 位图像的动态范围约 48dB,普通显示器的范围也大致在这一量级。但是真实物理场景的动态范围往往超过 100dB——直视太阳和阴影处的亮度差可达六个数量级以上。用单次曝光去拍摄这样的场景,要么亮部过曝成一片白,要么暗部欠曝成一片黑,无法同时记录两端的信息。

高动态范围成像(High Dynamic Range Imaging,HDRI)就是为这个问题设计的。它的思路很直接:用多张不同曝光量的照片分别记录场景的不同亮度区间,然后合成一张保留全范围信息的辐照度图,最后通过 Tone Mapping 压缩到显示器可呈现的范围。

多曝光图像序列#

对同一个静态场景,固定光圈、改变快门速度(或 ND 滤镜),拍摄一组曝光量等差或等比变化的照片:

  • 短曝光:保留高亮区域的细节,暗部几乎全黑。
  • 长曝光:保留暗部细节,亮部完全过曝。
  • 中间曝光:覆盖常规亮度区间。

理想情况下,每张照片中都有一个”有效曝光区间”——像素既不饱和也不欠曝。HDR 合成的目标就是从每张照片中挑出它的有效部分,拼成一张完整的辐照度图。

相机响应函数(CRF)#

上述过程无法直接操作,因为相机输出像素值与入射辐照度之间不是线性关系。传感器的光响应是线性的(光子数 \propto 电压),但经过伽马校正、白平衡、非线性去噪等一系列 ISP 处理后,最终输出的像素值 ZZ 与场景辐照度 EE 之间是一个未知的非线性映射。

定义曝光量 X=EΔtX = E \cdot \Delta t(辐照度 × 曝光时间),相机响应函数 ff 将曝光量映射到像素值:

Z=f(EΔt)Z = f(E \cdot \Delta t)

ff 是单调递增的,但我们不知道它的解析形式。反过来,如果我们能从多张曝光照片中恢复出 ff,就能将像素值反推出辐照度。

Debevec 算法恢复 CRF#

Debevec(1997)提出的方法至今仍是恢复 CRF 的经典方案。对同一场景的 NN 张照片,每张的曝光时间 Δtj\Delta t_j 已知。选取 PP 个空间位置,要求这些位置在 NN 张照片中都能找到对应像素(不过曝也不欠曝)。

对第 ii 个像素点、第 jj 张照片,有:

Zij=f(EiΔtj)Z_{ij} = f(E_i \cdot \Delta t_j)

两边取对数,记 g=lnf1g = \ln f^{-1}

g(Zij)=lnEi+lnΔtjg(Z_{ij}) = \ln E_i + \ln \Delta t_j

这里 gg 是待求解的函数(定义在离散灰度值 Z=0,,255Z=0,\dots,255 上,共 256 个未知数),lnEi\ln E_i 是每个像素点的未知辐照度(PP 个未知数)。Debevec 将求解转化为一个加权最小二乘问题:

O=i=1Pj=1Nw(Zij)[g(Zij)lnEilnΔtj]2+λz=1254w(z)[g(z)]2\mathcal{O} = \sum_{i=1}^{P} \sum_{j=1}^{N} w(Z_{ij}) \left[ g(Z_{ij}) - \ln E_i - \ln \Delta t_j \right]^2 + \lambda \sum_{z=1}^{254} w(z) \left[ g''(z) \right]^2

第一项确保拟合精度,第二项是平滑约束(惩罚 gg 的二阶差分)。权重函数 w(z)w(z) 在中间灰度值取最大值,在两端(z0z\approx0z255z\approx255)趋近于 0——过曝和欠曝的像素不可靠,不应参与拟合。

这是一个大型稀疏线性系统,通过 SVD 求解后即可得到完整的 CRF 曲线 gg

辐照度图合成#

有了 CRF,就可以将多张照片融合为一张高动态范围的辐照度图。对每个像素位置 (x,y)(x,y),用所有照片在该位置的有效像素值加权平均:

lnE(x,y)=j=1Nw(Zij)(g(Zij)lnΔtj)j=1Nw(Zij)\ln E(x,y) = \frac{\sum_{j=1}^{N} w(Z_{ij}) \left( g(Z_{ij}) - \ln \Delta t_j \right)}{\sum_{j=1}^{N} w(Z_{ij})}

权重 w(Z)w(Z) 同样是中间灰度值权重大、两端权重小。最终得到的是浮点格式的辐照度图(通常是 .hdr 或 .exr),动态范围可达 100dB 以上。这张图不能在普通显示器上直接查看,需要一个压缩步骤。

Tone Mapping#

Tone Mapping 将高动态范围辐照度图压缩到低动态范围(8bit/通道)的同时,尽量保留视觉细节和对比度感。

全局 Tone Mapping#

最简单的形式是 Gamma 映射和 Reinhard 全局算子:

Ld=L1+LL_d = \frac{L}{1 + L}

其中 LL 为归一化辐照度,LdL_d 为显示亮度。这个 S 形曲线在暗部近似线性(保留对比度),在亮部逐渐饱和(防止过曝),基本思路是”压低亮的、保持暗的”。全局映射的优点是速度快,缺点是局部对比度丢失——相邻区域只要有相近的绝对亮度,映射后就会被压成相近的显示值。

局部 Tone Mapping#

局部算子考虑每个像素周围的局部区域亮度。经典方法包括:

  • 基于 Retinex 理论:将图像分解为光照层和反射层,只压缩光照层。反射层包含了纹理细节,保留不动。
  • 基于引导滤波或双边滤波:用滤波结果做亮度分区,将全局映射改为逐区域自适应。较亮的区域接受更强的压缩,较暗的区域压缩较少甚至不压缩。

局部映射能更好地保持细节,代价是计算量更大,且可能在 Halo 伪影(强边缘附近出现光晕)。

HDR 与 ISP 的关系#

在相机 ISP pipeline 中,HDR 通常作为一个可选模块插入在 Demosaicing 之后、Tone Mapping 之前。手机上常见的方式有两种:

  • 多帧合成 HDR:连续拍摄多张不同曝光的 RAW 图,在 RAW 域合成 HDR 再走标准 ISP 流程。计算量大,但画质最好。
  • 单帧 HDR / DOL-HDR:传感器采用隔行交替曝光(长/短),一次读出两帧合成。适合视频录制。

无论哪种方案,从信号处理的角度看,核心始终是 Debevec 框架或它的硬件加速变体。

高动态范围成像:多曝光融合与Tone Mapping
https://biscuit0613.github.io/posts/cv/cv-img-hdr/
作者
Biscuit
发布于
2026-06-28
许可协议
CC BY-NC-SA 4.0
图像基础:颜色空间、直方图与伽马校正
CNN-BatchNorm