HDR图像合成硬件架构与RTL开发实战 - 第2节

多曝光图像序列:HDR的原材料

做HDR合成,第一步就是拿到多曝光图像序列。说白了,就是对着同一个场景,用不同的曝光时间拍好几张照片。你想想看,一张照片的动态范围有限,亮的地方过曝,暗的地方欠曝。但如果我们拍一组——一张欠曝、一张正常、一张过曝——就能把场景里从最亮到最暗的信息都抓全了。

我在项目中遇到过一个问题:图像序列的对齐精度。手持拍摄时,哪怕手抖一点点,像素就错位了。合成出来的HDR图像边缘会有鬼影,特别难看。所以硬件里一定要做运动补偿或者图像配准,这个后面章节会细讲。

曝光级别 曝光时间 保留信息 典型场景
欠曝 短 高亮区域细节 天空、灯光、反光面
正常 中 中间调细节 人物、建筑主体
过曝 长 暗部区域细节 阴影、背光面

嗯,这里要注意:多曝光序列的张数不是越多越好。3到5张是主流,再多的话,硬件处理带宽和存储开销会翻倍,收益却不大。

权重映射函数:给每个像素打分

拿到多张图像后,怎么决定每张图里哪些像素值得信任?这就是权重映射函数干的事。它的核心思想很简单:像素值太暗或太亮,噪声都大,不可靠;中间范围的像素最靠谱。

常见的权重函数有几种:

  • 三角权重:线性上升再下降,实现简单,但过渡不够平滑
  • 高斯权重:用高斯曲线,中间平坦,两边平滑下降,效果好
  • 平台权重:中间一段给满权重,两端快速衰减,硬件实现友好

我个人习惯用平台权重。为什么?因为硬件里做查表或者分段线性,比算高斯快得多。我在一个4K@60fps的项目里,就是用平台权重,流水线延迟只多了2个时钟周期。

权重函数的数学形式大概是这样:

// 伪代码:平台权重映射
function weight(pixel_value, threshold_low, threshold_high):
    if pixel_value < threshold_low:
        return pixel_value / threshold_low
    else if pixel_value > threshold_high:
        return (255 - pixel_value) / (255 - threshold_high)
    else:
        return 1.0

我曾经踩过一个坑:权重函数没做归一化。合成出来的图像整体偏暗,查了半天才发现是权重和不为1。后来我在RTL里加了一个归一化除法器,问题就解决了。

合成公式:把多张图揉成一张

有了权重,合成公式就顺理成章了。每个像素位置的最终值,是所有曝光图像在该位置的加权平均。

公式长这样:

HDR(x,y) = Σ( W_i(x,y) * I_i(x,y) ) / Σ( W_i(x,y) )

其中:

  • I_i(x,y) 是第i张曝光图像在(x,y)处的像素值
  • W_i(x,y) 是对应的权重
  • 分母是所有权重的和,保证归一化

你可能会问:为什么不用简单的最大值或者平均值?我试过,效果很差。最大值合成会丢失暗部细节,平均值合成会让亮部发灰。加权平均才是正道。

硬件实现小技巧:权重和分母可以用查找表预计算,避免实时除法。我在FPGA上就是这么干的,资源占用少了30%。

色调映射简介:把HDR塞进显示器

合成出来的HDR图像,像素值范围很大,可能是0到10000甚至更高。但普通显示器只能显示0到255。怎么办?这就需要色调映射。

色调映射的本质,就是把高动态范围压缩到低动态范围,同时尽量保留视觉细节。它不是简单的线性缩放——那样暗部会全黑,亮部会全白。

常见的色调映射算法分两类:

  • 全局映射:整张图用同一个映射曲线。实现简单,但局部对比度会丢失
  • 局部映射:根据像素周围区域调整映射参数。效果好,但硬件复杂度高

我记得在做一个监控摄像头项目时,用了全局映射。结果画面里同时有强光和阴影,细节全没了。后来换成局部映射,虽然逻辑多了不少,但效果立竿见影。

注意:色调映射不是HDR合成的必要步骤。如果你要输出真正的HDR格式(比如OpenEXR),就不需要映射。但绝大多数消费电子设备,最终都要映射到8bit或10bit输出。

本章知识体系

下面这张图,把HDR合成算法的核心流程串起来了:

HDR合成算法核心流程 多曝光图像序列 图像对齐/配准 权重映射函数 加权合成公式 色调映射 HDR/LDR输出 色调映射为可选步骤:输出HDR格式时可跳过,输出LDR格式时必须执行

从图上你能看到,整个流程是串行的:多曝光图像进来,先对齐,再算权重,然后加权合成,最后根据需求决定要不要做色调映射。每个环节都有硬件实现的考量和优化空间。

嗯,这一章的内容就到这里。核心概念就三个:多曝光序列、权重映射、合成公式。色调映射先有个印象,后面会有专门章节深入讲它的硬件实现。