4. 权重函数设计:像素权重计算、基于曝光的权重、基于饱和度的权重、基于梯度的权重

多帧融合的核心,说白了就是「怎么把几张图里最好的部分挑出来,拼成一张完美的图」。

你想想看,短曝光那帧暗部细节好,但亮部可能欠曝;长曝光那帧亮部层次丰富,但暗部可能死黑。怎么让算法知道「这里该用短曝光的像素,那里该用长曝光的像素」?

答案就是——权重函数。

我刚开始做HDR融合时,以为权重就是简单的线性插值。后来发现,事情远没那么简单。权重设计的好坏,直接决定了融合结果有没有鬼影、有没有噪声、细节是否丰富。

4.1 权重函数的基本概念

权重函数,就是给每个像素打一个「质量分」。分数越高,说明这个像素越值得被信任,在最终融合时占的比重大。

数学上,多帧融合可以表示为:

I_final(x,y) = Σ [ W_i(x,y) * I_i(x,y) ] / Σ W_i(x,y)

其中,W_i(x,y) 就是第 i 帧在位置 (x,y) 的权重。分母做归一化,保证总权重和为1。

权重设计有三个基本维度:

  • 曝光权重:像素亮度是否处于传感器的最佳响应区间
  • 饱和度权重:像素是否过曝或欠曝
  • 梯度权重:像素所在区域的纹理丰富程度

实际工程中,通常把这三种权重乘在一起,得到最终的融合权重。

关键点:权重函数必须是平滑的、连续的。如果权重在某个亮度值处突然跳变,融合结果就会出现明显的拼接痕迹。

4.2 基于曝光的权重

曝光权重是最直观的。每个像素都有一个「最佳曝光区间」——在这个区间内,传感器的信噪比最高,量化误差最小。

典型的曝光权重函数是一个高斯型曲线:

W_exp(I) = exp( - (I - I_mid)² / (2 * σ²) )

其中:

  • I 是像素亮度值(归一化到0~1)
  • I_mid 是中间灰度值,通常取0.5
  • σ 控制曲线的宽度,一般取0.2~0.3

这个函数的意思是:亮度在0.5附近的像素权重最高,越亮或越暗,权重越低。

我在项目中遇到过一个问题:直接用高斯权重,暗部区域的权重会变得非常小。结果就是,短曝光帧的暗部虽然信噪比低,但好歹有信号;长曝光帧的暗部虽然信噪比高,但可能已经饱和了。如果权重给得太极端,融合结果反而不好。

我的经验:实际工程中,我通常把σ设得大一些(0.3~0.4),让权重曲线更平坦。这样暗部和亮部都能保留一定的贡献,避免融合结果出现「断层」。

4.3 基于饱和度的权重

饱和度权重解决的是「过曝」和「欠曝」的问题。

过曝的像素(亮度接近1.0)已经失去了纹理信息,全是白色一片。欠曝的像素(亮度接近0.0)被噪声淹没,信噪比极低。这两种像素都应该被「惩罚」——权重设为0或接近0。

饱和度权重的设计思路很简单:

W_sat(I) = 
  0,                    if I < I_low_thresh
  (I - I_low_thresh) / (I_mid - I_low_thresh),  if I_low_thresh ≤ I < I_mid
  1,                    if I_mid ≤ I < I_high_thresh
  (1.0 - I) / (1.0 - I_high_thresh),            if I_high_thresh ≤ I < 1.0
  0,                    if I ≥ 1.0

说白了,就是中间一段给满分,两端逐渐降为0。

阈值怎么选?我一般这样设:

参数 推荐值 说明
I_low_thresh 0.05 ~ 0.10 低于此值视为欠曝,权重为0
I_high_thresh 0.90 ~ 0.95 高于此值视为过曝,权重为0
I_mid 0.50 最佳曝光点

注意:饱和度权重和曝光权重不要「双重惩罚」。我曾经犯过这个错误——曝光权重已经给暗部打了低分,饱和度权重又给暗部打了一次低分。结果暗部权重几乎为0,融合结果暗部全是噪声。正确的做法是:曝光权重和饱和度权重取其一,或者让饱和度权重只处理极端情况。

4.4 基于梯度的权重

梯度权重是我个人觉得最有意思的一个维度。

它的核心思想是:纹理丰富的区域,权重应该更高。为什么?因为纹理区域包含了更多的图像信息,而且人眼对纹理区域的失真更敏感。

梯度权重的计算:

G(x,y) = sqrt( Gx² + Gy² )

其中 Gx 和 Gy 是Sobel算子计算的水平和垂直梯度。

然后,把梯度映射到权重:

W_grad(x,y) = min( G(x,y) / G_max, 1.0 )

或者用更平滑的方式:

W_grad(x,y) = 1 - exp( -G(x,y) / τ )

其中 τ 控制梯度响应的灵敏度,一般取0.1~0.3。

梯度权重有个很实用的场景:消除鬼影。

你想想看,如果场景中有运动物体,不同帧之间同一个位置的梯度会发生变化。运动区域的梯度权重会降低,从而减少运动物体对融合结果的贡献。这就是梯度权重在「运动检测」中的妙用。

实战技巧:梯度权重不要单独使用,一定要和曝光权重或饱和度权重配合。否则,纯黑区域(梯度为0)和纯白区域(梯度也为0)都会被赋予低权重,但原因完全不同——一个是欠曝,一个是过曝。只有结合曝光信息,才能正确区分这两种情况。

4.5 多权重融合策略

实际工程中,我们通常把三种权重组合起来。组合方式有两种:

  1. 乘法组合:W_total = W_exp * W_sat * W_grad
  2. 加权组合:W_total = α*W_exp + β*W_sat + γ*W_grad

我个人习惯用乘法组合。因为乘法组合是「与」的关系——一个像素必须在曝光、饱和度和纹理三个方面都表现良好,才能获得高权重。加权组合是「或」的关系,某个维度得分高就能拉高总分,容易引入质量差的像素。

下面是我常用的权重计算流程:

// 伪代码:多帧融合权重计算
for each frame i:
    for each pixel (x,y):
        // 1. 计算曝光权重
        w_exp = exp( - (I_i(x,y) - 0.5)² / (2 * 0.3²) )
        
        // 2. 计算饱和度权重
        if I_i(x,y) < 0.05:
            w_sat = 0
        elif I_i(x,y) > 0.95:
            w_sat = 0
        else:
            w_sat = 1.0
        
        // 3. 计算梯度权重
        grad = sobel_gradient(I_i, x, y)
        w_grad = 1 - exp( -grad / 0.2 )
        
        // 4. 组合权重
        W_i(x,y) = w_exp * w_sat * w_grad
    
    // 5. 空间平滑(可选)
    W_i = gaussian_blur(W_i, sigma=3)

避坑指南:最后一步的空间平滑很重要。如果不做平滑,权重在像素级别剧烈变化,融合结果会出现「颗粒感」。我一般用3x3或5x5的高斯核做一次平滑,让权重过渡更自然。

4.6 权重函数设计全景图

下面这张图展示了权重函数设计的完整知识体系:

权重函数设计知识体系 融合权重 W_total 曝光权重 W_exp 饱和度权重 W_sat 梯度权重 W_grad 高斯型曲线:W=exp(-(I-0.5)²/2σ²) σ=0.2~0.4,控制曲线宽度 分段线性:中间满分,两端降0 阈值:I_low=0.05, I_high=0.95 W=1-exp(-G/τ),τ=0.1~0.3 可检测运动区域,消除鬼影 组合策略:乘法 vs 加权 后处理:空间平滑(高斯模糊) 核心原则:平滑过渡、避免双重惩罚、乘法组合优于加权组合

4.7 实战中的注意事项

权重设计看起来简单,但实际调参时坑很多。我总结几个常见问题:

  • 权重太陡:融合结果出现明显的「拼接缝」。解决方案是增大σ或使用更平滑的权重函数。
  • 权重太平:融合结果没有充分利用各帧的优势。解决方案是适当减小σ,让权重更有区分度。
  • 忽略空间一致性:相邻像素的权重差异过大,导致融合结果出现「颗粒感」。解决方案是加空间平滑。
  • 权重计算太慢:每个像素都要计算指数函数,性能开销大。解决方案是用查找表(LUT)预计算权重曲线。

性能优化建议:权重计算不要逐像素做指数运算。我一般把亮度值量化到256级,预计算一个256长度的权重查找表。运行时直接查表,速度提升10倍以上。

嗯,权重函数设计就讲到这里。记住一句话:好的权重函数,是让每帧图像只贡献它最擅长的部分。曝光好的区域贡献细节,纹理丰富的区域贡献结构,中间调的区域贡献色彩。这样融合出来的HDR图像,才能既自然又丰富。