3、多帧HDR原理:短中长曝光如何合成一张高动态图?——鬼影与对齐的挑战。
多帧HDR,说白了就是拍三张照片,然后合成一张。一张欠曝(短曝光),一张正常(中曝光),一张过曝(长曝光)。
为什么要这么干?因为单张照片的动态范围有限。暗的地方提亮了全是噪点,亮的地方压暗了全是死白。三张合在一起,暗部用长曝光的细节,亮部用短曝光的纹理,中间用中曝光过渡。嗯,听起来很完美,对吧?
但现实很骨感。我最早做HDR项目时,以为只要把三张图叠在一起就行。结果合成出来的照片,移动的行人变成了半透明的幽灵,晃动的树枝像被PS涂抹过一样。这就是鬼影——多帧HDR最大的坑。
3.1 短中长曝光的核心逻辑
先讲清楚三张图各自负责什么区域。你可以把场景的亮度想象成一条横轴,从最暗到最亮。
| 曝光类型 | 负责区域 | 典型问题 |
|---|---|---|
| 短曝光(1/120s) | 高光区域(天空、灯箱、反光面) | 暗部全是噪点,几乎全黑 |
| 中曝光(1/30s) | 中间调(人脸、建筑、地面) | 高光可能过曝,暗部噪点明显 |
| 长曝光(1/4s) | 暗部区域(阴影、夜景、室内角落) | 高光完全过曝,运动物体模糊 |
合成时,我们用一个权重曲线来融合。高光区域给短曝光高权重,暗部区域给长曝光高权重,中间区域平滑过渡。这个权重曲线设计得好不好,直接决定合成结果的自然度。
关键指标: 合成后的图像,暗部信噪比提升约 2-3 档,高光细节保留提升约 1-2 档。如果达不到这个水平,说明你的权重曲线或者对齐算法有问题。
3.2 鬼影是怎么产生的?
鬼影的本质,是同一物体在三张图中的位置不一致。比如一个人从左边走到右边,短曝光时他在位置A,长曝光时他在位置B。合成时,位置A和位置B的像素被强行融合,结果就是半透明的重影。
为什么会这样?因为三张图不是同时拍的。手机上的多帧HDR通常是快速连拍,但再快也有几十毫秒到几百毫秒的间隔。对于静止场景,这个间隔无所谓。但对于运动物体,这个间隔就是鬼影的温床。
避坑指南: 我曾经在夜景人像项目里踩过这个坑。用户手持拍摄,三帧间隔约 200ms,模特轻微晃动了一下。结果合成后,模特的头发边缘出现了明显的鬼影,像长了两个下巴。后来我们不得不加入运动检测,对脸部区域做特殊保护。
鬼影的严重程度取决于三个因素:
- 运动速度: 物体移动越快,鬼影越明显。
- 曝光间隔: 三帧之间的时间差越大,鬼影越严重。
- 物体对比度: 边缘越锐利(比如文字、栏杆),鬼影越刺眼。
3.3 对齐算法:从全局到局部
要消除鬼影,第一步是对齐。对齐的目的是让三张图的背景完全重合,这样合成时只有运动物体才会产生差异。
对齐算法分两个层次:
- 全局对齐(Global Alignment): 用仿射变换或透视变换,校正相机抖动造成的整体偏移。这个相对简单,用特征点匹配(比如SIFT、ORB)或者相位相关就能搞定。
- 局部对齐(Local Alignment): 对运动区域做光流估计或块匹配,把运动物体也尽量对齐。这个难度大很多,因为运动物体的形状和位置都在变化。
我个人习惯的做法是:先做全局对齐,再做局部对齐。全局对齐解决相机抖动,局部对齐解决物体运动。两步走,效果比一步到位好得多。
实战技巧: 局部对齐时,不要对整个图像做光流。只对检测到的运动区域做光流,可以节省 70% 以上的计算量。我在手机端项目里就是这么干的,帧率从 5fps 提升到了 20fps。
3.4 鬼影检测与去除策略
对齐做得再好,运动物体也不可能完全对齐。这时候就需要鬼影检测和去除。
鬼影检测的核心思路是:比较对齐后的三张图,找出差异大的区域。差异大的地方,就是鬼影候选区。
常用的检测方法:
- 像素级差异: 计算三帧之间的差,设定阈值。简单粗暴,但容易误检(比如噪声也会产生差异)。
- 梯度差异: 比较边缘信息。运动物体的边缘通常会有明显的梯度变化,比像素级差异更鲁棒。
- 运动向量: 用光流法计算运动向量,向量大的区域就是运动区域。
检测到鬼影区域后,怎么去除?有三种主流策略:
| 策略 | 做法 | 优缺点 |
|---|---|---|
| 丢弃法 | 鬼影区域只用单帧数据,不融合 | 简单,但可能造成亮度突变 |
| 权重法 | 鬼影区域降低运动帧的权重 | 过渡自然,但参数难调 |
| 替换法 | 用中曝光帧替换鬼影区域 | 效果稳定,但中曝光帧可能过曝或欠曝 |
我建议的做法是:对鬼影区域做权重法,但权重不是固定的,而是根据运动幅度动态调整。运动幅度越大,运动帧的权重越低。这样既能消除鬼影,又能保留一定的纹理细节。
3.5 多帧HDR合成流程总览
下面这张图展示了完整的合成流程,从三帧输入到最终输出:
3.6 实战中的权衡与取舍
讲完理论,说点实际的。在真实项目中,你不可能把每个环节都做到完美。计算资源有限,功耗有限,延迟有限。你需要做权衡。
我总结了几条经验:
- 对齐精度 vs 计算量: 光流法精度高,但手机端跑不动。块匹配是更好的选择,配合金字塔结构,精度和速度都能接受。
- 鬼影检测灵敏度 vs 误检率: 阈值设低了,鬼影去不干净;阈值设高了,会把正常纹理当成鬼影去掉。我建议用梯度差异做初筛,再用运动向量做确认,两步法可以降低误检率。
- 融合质量 vs 处理速度: 逐像素权重计算很慢。可以用分块权重,或者预计算权重查找表。我在一个项目中把融合速度从 30ms 降到了 8ms,代价是质量损失不到 1%。
核心结论: 多帧HDR的成败,不在于三张图拍得多好,而在于鬼影处理得干不干净。对齐是基础,鬼影检测是关键,融合策略是最后一道防线。三者缺一不可。
嗯,这一章的内容就到这里。多帧HDR的原理听起来简单,但落地时每一步都有坑。希望这些经验能帮你少走弯路。