3、相机响应函数:CRF 的定义、测量与 HDR 应用

相机响应函数,英文叫 Camera Response Function,简称 CRF。这东西说白了,就是描述「场景中的真实亮度」和「相机像素值」之间映射关系的一条曲线。

你可能会想,这不就是一条 gamma 曲线吗?还真不是。Gamma 只是 CRF 的一个简化近似。真实的 CRF 包含了传感器光电转换、模拟增益、ADC 量化、去马赛克、色调映射等一系列非线性操作。我刚开始做 HDR 时,直接用 gamma 2.2 去反推辐照度,结果合成出来的图像亮部一片死白,暗部全是噪声。后来才明白,不标定 CRF,多帧融合就是空中楼阁。

3.1 CRF 的定义

数学上,CRF 可以写成:

Z = f(E · Δt)

其中:

  • Z:像素输出值(0~255 或 0~4095)
  • E:场景辐照度(Irradiance)
  • Δt:曝光时间
  • f(·):相机响应函数,单调递增且非线性

注意,f 是单调递增的,否则会出现亮度反转——亮的变暗,暗的变亮,这在实际相机中不可能发生。但 f 不一定是光滑的,有些相机在低亮区有死区,在高亮区有饱和区。

关键理解:CRF 的逆函数 f⁻¹ 可以把像素值 Z 映射回相对辐照度 E·Δt。这就是 HDR 合成的数学基础。

3.2 CRF 的测量方法

测量 CRF 有两种主流思路:

  1. 使用均匀光源 + 中性密度滤光片:改变 ND 值,记录像素变化。精度高,但需要专业设备。
  2. 使用多曝光图像序列:固定场景,改变曝光时间,从多帧中恢复 CRF。这就是 Debevec 和 Robertson 方法的思路。

我个人更推荐第二种,因为它不需要额外硬件,用你手头的相机就能做。我在项目中曾经用一台工业相机,拍了 12 帧不同曝光的灰阶卡,然后用 Debevec 方法标定 CRF,效果相当不错。

3.2.1 多曝光标定流程

步骤 操作 注意事项
1 固定相机,拍摄静态场景 场景必须完全静止,三脚架固定
2 改变曝光时间,拍摄 N 帧 曝光时间覆盖 1/1000s ~ 30s,至少 6 帧
3 选取 P 个采样点 选在纹理丰富区域,避开过曝/欠曝
4 构建超定方程组 用最小二乘法求解 CRF 和辐照度
5 平滑与插值 得到完整的 CRF 曲线

小技巧:采样点不要选在纯色区域,否则方程会退化。我习惯选在边缘或纹理密集的地方,这样约束更强,求解更稳定。

3.3 CRF 在 HDR 中的作用

CRF 在 HDR 合成中扮演着「翻译官」的角色。没有它,不同曝光帧的像素值无法直接比较。举个例子:

  • 短曝光帧中,像素值 128 可能对应场景中很亮的部分
  • 长曝光帧中,像素值 128 可能对应场景中较暗的部分
  • 如果不做 CRF 逆映射,直接平均这两个 128,结果毫无意义

CRF 逆映射后,我们把所有帧的像素值统一到「辐照度 × 曝光时间」空间,然后才能进行加权融合。这就是 HDR 合成的核心步骤。

避坑指南:我曾经遇到过一个项目,用手机拍摄的多帧 HDR,直接套用标准 CRF 曲线,结果合成图像偏色严重。后来发现,手机 ISP 在拍照时自动做了白平衡和色调映射,改变了 CRF 形状。所以,每台相机的 CRF 都必须单独标定,不能通用。

3.4 Debevec 与 Robertson 方法

这两种方法都是通过多曝光图像序列来恢复 CRF,但思路略有不同。

3.4.1 Debevec 方法(1997)

Debevec 的方法基于一个假设:CRF 是光滑且单调的。他把问题转化为一个最小二乘优化:

目标函数:O = Σ Σ [w(Z_ij) · (g(Z_ij) - ln(E_i) - ln(Δt_j))]² + λ · Σ [w(Z) · g''(Z)]²

其中:

  • g = ln(f⁻¹):逆 CRF 的对数形式
  • w(Z):权重函数,中间像素权重大,两端权重小
  • λ:光滑性约束系数
  • g'':二阶导数,强制曲线光滑

这个优化可以分解为两个交替步骤:

  1. 固定 CRF,求解每个采样点的辐照度 E_i
  2. 固定辐照度,更新 CRF 曲线 g

迭代直到收敛。Debevec 方法对噪声比较敏感,但结果很稳定。我最早实现 HDR 时用的就是 Debevec 的代码,虽然慢,但效果扎实。

3.4.2 Robertson 方法(2003)

Robertson 的方法引入了概率模型。他认为,像素值 Z 的观测噪声服从高斯分布,CRF 的求解可以转化为最大似然估计:

最大化:P(Z | E, f) = Π Π (1/√(2πσ²)) · exp(-(Z_ij - f(E_i · Δt_j))² / (2σ²))

取对数后,等价于最小化加权平方误差。Robertson 方法的特点是:

  • 对噪声更鲁棒:因为显式建模了噪声分布
  • 收敛更快:通常 5~10 次迭代即可
  • 可以处理欠曝和过曝区域:通过调整权重函数

对比总结:Debevec 方法适合高质量、低噪声的场景;Robertson 方法适合噪声较大或曝光范围极端的场景。我个人在工程中更常用 Robertson,因为它对硬件不完美的容忍度更高。

3.4.3 两种方法的对比表格

维度 Debevec 方法 Robertson 方法
数学基础 最小二乘 + 光滑约束 最大似然估计
噪声处理 通过权重函数抑制 显式建模噪声分布
收敛速度 较慢,需 20~50 次迭代 较快,5~10 次迭代
实现复杂度 中等 稍高(需估计噪声方差)
适用场景 实验室标定、高质量合成 移动端、实时系统、噪声环境

3.5 CRF 恢复的完整流程(SVG 图)

下面这张图展示了从多曝光图像到 CRF 曲线的完整流程:

CRF 恢复流程图 CRF 恢复流程图 多曝光图像序列 选取 P 个采样点 构建超定方程组 迭代求解 CRF 收敛? 否 是 输出 CRF 曲线 说明: Debevec 方法使用最小二乘 + 光滑约束,Robertson 方法使用最大似然估计。 两种方法都依赖多曝光图像序列,且需要迭代求解。

3.6 实战建议

如果你要在项目中实现 CRF 标定,我有几点建议:

  • 曝光时间要覆盖足够范围:至少 6 帧,最好 12 帧以上。曝光比建议 2 倍或 4 倍递增。
  • 场景选择很重要:用灰阶卡或自然场景都行,但一定要有丰富的亮度变化。纯白墙不行。
  • 注意 RAW 和 JPEG 的区别:RAW 的 CRF 更接近线性,JPEG 已经做了 gamma 和色调映射,CRF 更弯曲。我建议用 RAW 做标定,精度更高。
  • 权重函数要合理:Debevec 的权重函数是三角形状,中间权重大,两端权重小。Robertson 的权重函数基于噪声模型,更科学。

经验之谈:如果你只是做算法验证,可以用 Debevec 的经典代码,网上有开源实现。但如果是产品化,我建议用 Robertson 方法,因为它对工程中的各种「脏数据」更宽容。我曾经在一个项目中,相机曝光时间有 5% 的误差,Debevec 方法直接发散,Robertson 方法还能收敛出可用的 CRF。

好了,CRF 的内容就讲到这里。记住,CRF 是 HDR 合成的基石,花时间把 CRF 标定做好,后面的融合工作会顺利很多。