ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于新型金字塔滤波器的非对称自适应红外与可见光图像融合

基于新型金字塔滤波器的非对称自适应红外与可见光图像融合 最近在做图像融合方向的实验正好复现了一套基于新型金字塔滤波器的非对称自适应多尺度分解方法用来做红外和可见光图像融合。从原理到Matlab源码再到调参踩坑前后折腾了两周多。这篇文章就把这套方法的完整思路和实操细节整理出来包括金字塔分解为什么是融合的主流框架、所谓非对称自适应到底改了什么、融合规则怎么设计以及源码里最容易出问题的几个环节。红外和可见光图像融合这个方向做安防监控、夜间辅助驾驶、遥感侦察的朋友应该都不陌生。可见光图像纹理细节丰富但一到夜间或者低照度环境就抓瞎红外图像靠热辐射成像不受光照影响但分辨率低、纹理信息少看过去就是一团模糊的亮斑。融合的目标很直接把两种图像的优点叠到一张图上白天黑夜都能看清。方法层面多尺度分解是图像融合里非常经典的一条路线金字塔结构就是其中最常见的载体。传统的拉普拉斯金字塔虽然好用但固定参数、固定层数处理红外和可见光这两种差异巨大的图像时并不够灵活。这套方法的核心改进在于用了一种新型滤波器构建金字塔并且对两路输入图像采用非对称的自适应分解策略最后在融合规则上做精细化的低频和高频处理。简单说就是让分解过程看人下菜碟不同模态的图像走不同的分解参数融合效果确实比传统金字塔方法干净不少。下面按我实际复现的顺序把整条链路拆开讲。1. 红外与可见光的差异决定了融合方法不能一刀切1.1 两种成像机制的本质区别先把最基础的东西讲清楚。红外图像记录的是物体表面的热辐射差异理论上在完全无光的夜晚也能成像这是它最大的优势。但热辐射图像天生有两个毛病一是空间分辨率低边缘模糊二是灰度分布集中对比度差。很多时候你看红外图像里一个人形亮斑只能看出轮廓完全看不清衣服纹理或者面部细节。可见光图像记录的是物体对光源的反射纹理丰富、边缘锐利视觉上非常符合人眼习惯。但它对光照条件极其敏感夜间一旦没有补光画面基本就是一片死黑或者噪点翻涌。两种图像一个看得见但不清晰一个清晰但看不见信息结构是完全互补的。融合的目标就是把红外的目标显著性信息和可见光的场景纹理信息合并到一张图上。理解了这一点你就会明白为什么融合方法不能简单地对两幅图做加权平均——加权平均的结果往往是两边的缺点同时被保留红外目标的亮度被稀释可见光的细节也被压低。1.2 像素级融合为什么离不开多尺度分解图像融合分三个层次像素级、特征级、决策级。这套方法属于像素级融合好处是保留的信息量最大坏处是容易产生伪影。而像素级融合里直接对整幅图像做加权平均是效果最差的方案原因在于真实图像里的信息分布在不同的频率层面上大片的平滑区域是低频信息边缘、纹理、噪点是高频信息。不同频率成分应该采用不同的融合策略这就引出了多尺度分解的必要性。多尺度分解的思路本质上是分而治之先把图像拆成若干不同频率的子带低频子带保留整体亮度和结构高频子带保留细节和边缘然后对不同子带用差异化的规则融合最后逆变换重建出融合图像。这套思路在信号处理里其实就是把图像分解成分层的图纸每一层负责一个频段的信息。1.3 为什么选金字塔而不是小波做多尺度分解可选的工具不少最常见的就是金字塔和小波。小波变换在频域上的划分更精细还有方向选择性但缺点是平移不变性差——图像稍微平移一点小波系数就大变融合结果容易产生马赛克式的块状伪影。金字榠分解实现简单、计算量小、平移不变性天然优于小波所以工程落地用得更普遍。这套方法选择金字塔也是看重它的稳定性和易实现性。2. 金字塔分解的核心逻辑以及新型滤波器究竟改了什么2.1 高斯金字塔与拉普拉斯金字塔的基本盘传统金字塔分解分两步走。第一步构建高斯金字塔对原图做高斯卷积然后隔行隔列下采样得到缩小一半的图像重复这个过程若干次就得到一组分辨率逐层减半的高斯金字塔每一层相当于上一层的低通滤波降采样结果。第二步构建拉普拉斯金字塔把高斯金字塔的某一层上采样回上一层尺寸再做高斯卷积然后与上一层原始图像做差。这个差值就是高频细节层。说白了拉普拉斯金字塔保存的是每层模糊后丢失的信息。重建的时候从最顶层的低频残差开始逐层上采样并叠加对应的高频细节层就能恢复到原始图像。这个正变换和逆变换的过程是完备的——不丢失信息只是换了一种表达方式。融合时我们就在这个表达方式上分别处理不同频率成分。2.2 传统拉普拉斯金字塔在高频细节上有三个先天短板我在复现过程中对比了传统拉普拉斯金字塔的效果发现它有几个绕不开的问题。第一高频子带缺乏方向选择性。拉普拉斯金字塔的每一层是对高斯模糊前后差异的简单提取它只能告诉你这里有没有细节但说不清这个细节是水平方向的还是垂直方向的。融合的时候如果两幅图在同一位置都有边缘但方向不同简单的系数取大或加权平均容易把边缘糊掉。第二对噪声敏感。红外图像本身噪声不少高频通道对噪声同样响应很强。传统拉普拉斯金字塔分解得到的多层高频子带里噪声被逐层放大融合时如果不加处理结果图上会出现密密麻麻的椒盐状噪点。第三高斯核参数固定平滑区域容易产生振铃效应。在灰度变化剧烈的边缘附近简单高斯卷积后重建常常会出现一圈一圈的明暗交替伪影专业术语叫振铃。2.3 新型金字塔滤波器在滤波核上做文章这套方法改进的第一刀切在了滤波核上。传统方法用标准的高斯核做模糊对图像里的边缘和平坦区域一视同仁。新型金字塔滤波器则引入了一种边缘保持的滤波思想——在平滑区域用正常的高斯模糊压低噪声在边缘附近降低模糊强度保留边缘锐度。具体实现上可以借助引导滤波或者双边滤波的思路来替代高斯核。引导滤波以源图像自身作为引导图在边缘处能保持梯度结构在平坦区域则退化为普通的平滑操作。我在Matlab里实测用引导滤波替换高斯核构建金字塔之后融合结果里的振铃伪影明显减少边缘更加干净。另一个小改进是滤波核的方向性。传统高斯核是各向同性的各方向模糊程度相同。改进后的滤波器可以在水平、垂直、对角方向分别设置不同的滤波强度这样高频子带里就保留了方向信息融合时能更好地保留不同走向的边缘纹理。这个思路在小波变换里很常见但用在金字塔结构里实现更简单计算量也小。2.4 非对称自适应分解两路图像各自合适的分解深度这是整套方法里最核心的设计。传统金字塔融合对两幅源图像用相同的分解层数、相同的滤波参数看起来公平但实际效果并不理想。原因在于红外和可见光图像的能量分布完全不同。红外的信息主要集中在低频——目标区域的热辐射差异是整体性的高频细节本身就少。可见光图像则相反高频细节极其丰富低频反而因为光照不均匀带有大量亮度起伏。如果强迫两幅图分解同样的层数可能出现两种情况要么可见光的高频细节在融合中被压制要么红外的噪声在高频通道里被当作细节保留下来。非对称策略的思路是红外图像分解少几层比如3层因为它在更深层已经没有多少有效细节可见光图像分解多几层比如5层把丰富的纹理信息充分展开。融合时二者在对应层上做融合红外没有涉及到的更深层细节直接取自可见光这样两边的优势都能保住。自适应则体现在分解参数的确定上。分解层数和滤波核的尺度可以根据图像内容自动调整。我在实现时用的指标是图像的信息熵和梯度幅值信息熵高说明细节丰富可以加深分解层数梯度幅值大说明边缘集中滤波核的尺度可以适当调小。这个判断逻辑在Matlab里用entfilt和imgradient就能算代码量不大效果提升却很直观。3. 融合规则设计低频保能量高频保结构金字塔分解完之后手里的材料是若干层高频细节子带加一层低频残差子带红外和可见光各有一套。融合规则就是决定怎么把这两套子带合并成一套。3.1 低频子带自适应显著性权重替代固定加权平均低频子带代表图像的整体亮度和结构骨架。传统方法里最常见的操作是加权平均红外和可见光各取0.5的权重直接相加。这个做法简单但问题在于如果红外图像目标的亮度显著高于可见光背景0.5的权重会直接把目标的亮度拉低一半融合图上目标就没那么显眼了。这套方法在低频融合上采用了基于显著性图的自适应权重。先用一个滑动窗口计算低频子带每个像素周围的局部能量作为该点的显著性度量然后构造权重图% 计算低频子带的局部能量图 window fspecial(average, [5 5]); energy_ir filter2(window, low_ir .^ 2, same); energy_vis filter2(window, low_vis .^ 2, same); % 构造自适应权重图 w_ir energy_ir ./ (energy_ir energy_vis eps); w_vis 1 - w_ir; % 低频融合 low_fused w_ir .* low_ir w_vis .* low_vis;权重图的意义很清楚哪个源图像在这个局部区域更有料就给它更高的权重。红外图像里目标区域能量高权重自然向红外倾斜目标的亮度就能保住可见光图像里背景区域有更多结构信息权重就偏向可见光。eps加上是为了防止除零这个细节别漏了。3.2 高频子带区域能量取大比像素取大更稳高频子带融合的核心指标是活性度量——判断哪个图像在这个像素位置的细节更明显。最简单的方案是绝对值取大谁的系数绝对值大就选谁。这个方案在无噪声的理想情况下效果还行但红外图像的高频包含大量噪声噪声的绝对值也不小做像素级取大很容易把噪声也当作细节选进来。更稳的方案是区域能量取大。以每个像素为中心开一个3×3或5×5的窗口计算窗口内所有系数的能量之和作为该点的活性度量。然后在两幅图之间比较这个能量值谁的能量大选谁。function fused_high fuse_high_level(high_ir, high_vis, winsize) % 区域能量计算 h fspecial(average, [winsize winsize]); energy_ir filter2(h, high_ir .^ 2, same); energy_vis filter2(h, high_vis .^ 2, same); % 能量取大决策 fused_high high_ir; mask energy_vis energy_ir; fused_high(mask) high_vis(mask); end区域能量取大的好处是抗噪单个像素的噪声尖峰在窗口内的能量占比通常不大不会干扰决策而真正的纹理边缘往往是成片出现窗口内能量会显著高于噪声区域。我实测下来的感受是窗口大小对结果影响不小。3×3窗口边缘更锐但抗噪弱7×7窗口抗噪强但边缘会有轻微的细节丢失看起来稍微肉一点。我的常用配置是5×5平衡度最好。如果源图像分辨率高超过1000×10007×7也可以接受。3.3 融合伪影的抑制权重图平滑与边界填充高频融合用硬决策选A或选B的一个副作用是两幅图的系数在空间上可能不连续融合结果上会出现拼接痕迹。解决办法是对决策图做一次高斯模糊把硬决策变成软决策让融合结果在空间上平滑过渡。% 对决策图做高斯平滑 mask_smooth imgaussfilt(double(mask), 1.2); fused_high mask_smooth .* high_vis (1 - mask_smooth) .* high_ir;这个操作代价很小但对视觉质量的提升非常明显。做完之后融合图上的拼接线基本就看不出来了。还有一个容易被忽略的细节金字塔分解时的边界处理。Matlab的filter2和imgaussfilt默认在图像边界做补零操作这会导致边界处的分解系数异常重建之后边界出现一圈暗边。解决方案是在分解之前主动填充图像边界% 对称填充边界避免分解伪影 img_padded padarray(img, [10 10], symmetric); % 分解完成后裁剪回原尺寸对称填充比补零好很多因为对称填充保持了图像在边界处的连续性分解系数不会出现突变。4. Matlab源码核心模块拆解与参数配置4.1 整体文件结构与运行流程我复现的版本把整个流程拆成了四个文件职责划分清晰调试起来也方便main_fusion.m主脚本负责读图、参数配置、调用分解和融合、显示结果pyramid_decompose.m金字塔分解函数输入图像和参数输出金字塔结构体一个cell数组fusion_core.m融合主函数输入红外和可见光的金字塔结构体输出融合后的金字塔pyramid_reconstruct.m金字塔重建函数把融合后的金字塔恢复到完整图像运行流程很直接读图 → 归一化 → 两路分别做金字塔分解 → 逐层融合 → 重建 → 转回uint8显示。关键就在两路分别做金字塔分解这一步因为这里用到了非对称参数。4.2 金字塔分解函数的关键代码金字塔分解函数是整套方法的基石。我贴一下核心代码注释写得很详细方便直接跑function pyr pyramid_decompose(img, levels, filter_size, sigma) % 基于引导滤波的金字塔分解 % 输入: % img - double类型灰度图, 范围[0,1] % levels - 分解层数 % filter_size - 引导滤波窗口大小 % sigma - 平滑程度参数 % 输出: % pyr - 1x(levels1)的cell数组 % pyr{1..levels}为高频细节层 % pyr{levels1}为低频残差层 pyr cell(1, levels 1); current img; for i 1:levels % 使用引导滤波替代普通高斯滤波, 边缘保持更好 blurred imguidedfilter(current, current, ... NeighborhoodSize, filter_size, ... DegreeOfSmoothing, sigma^2); % 下采样 down blurred(1:2:end, 1:2:end); % 上采样回原尺寸 up imresize(down, [size(current,1), size(current,2)], bilinear); % 高频细节 当前层 - 上采样后的低频 pyr{i} current - up; % 进入下一层 current down; end % 最后一层保存低频残差 pyr{levels 1} current; end几个容易踩坑的细节第一imguidedfilter是Image Processing Toolbox的函数版本太老的Matlab可能没有。如果没有可以用im双边滤波imbilatfilt替代效果接近但速度更慢一些。第二上采样我用了imresize的双线性插值。理论上更规范的做法是先插零再卷积但在实际测试中imresize的双线性插值配合引导滤波重建出来的图像与原始图像的误差在1e-10量级视觉上完全看不出区别所以直接用。第三DegreeOfSmoothing参数需要手动设置。设置越大平滑程度越高细节层保留的纹理越少。这个参数就是非对称的载体之一——红外图像可以设置大一点的平滑度例如0.05抑制噪声可见光设置小一点例如0.01保留更多纹理。4.3 融合主函数与自适应权重实现融合主函数接受两个金字塔结构体逐层融合。我贴一下完整结构function fused_pyr fusion_core(pyr_ir, pyr_vis, winsize) % 输入: % pyr_ir - 红外图像的金字塔 % pyr_vis - 可见光图像的金字塔 % winsize - 区域能量计算的窗口大小 % 输出: % fused_pyr - 融合后的金字塔 levels_ir length(pyr_ir); levels_vis length(pyr_vis); % 融合后的金字塔层数为两者中的较大值 max_levels max(levels_ir, levels_vis); fused_pyr cell(1, max_levels); % 高频层融合: 区域能量取大 for i 1:max_levels - 1 if i levels_ir % 红外没有更深的细节层, 直接取可见光 fused_pyr{i} pyr_vis{i}; elseif i levels_vis % 可见光没有更深的细节层, 直接取红外 fused_pyr{i} pyr_ir{i}; else % 两路都有: 区域能量取大 fused_pyr{i} fuse_high_level(pyr_ir{i}, pyr_vis{i}, winsize); end end % 低频层融合: 自适应显著性权重 low_ir pyr_ir{levels_ir}; low_vis pyr_vis{levels_vis}; % 如果分辨率不一致, 需要先对齐 if ~isequal(size(low_ir), size(low_vis)) low_vis imresize(low_vis, size(low_ir), bilinear); low_ir imresize(low_ir, size(low_vis), bilinear); end fused_pyr{max_levels} fuse_low_level(low_ir, low_vis); end这个函数里的非对称逻辑体现在红外分解了3层可见光分解了5层那么融合时第4层、第5层的细节就直接取可见光的因为红外在这些深度已经没有有效信息了。4.4 参数初始化建议我这套实现里推荐一组相对通用的初始参数参数推荐值说明红外分解层数3红外高频细节少太多层只会引入噪声可见光分解层数5可见光纹理丰富需要更深的分解来充分展开引导滤波窗口5×58×8效果更好但计算时间翻倍红外平滑度0.05平滑多抑制红外噪声可见光平滑度0.01保留更多可见光纹理区域能量窗口5×5抗噪与边缘保留的平衡点这组参数在TNO数据集和多组自采数据上都能跑出不错的效果。但强烈建议根据自己的输入图像做调整——如果红外图像本身很干净比如高端制冷型红外相机拍的平滑度可以降低到0.02多保留一些红外自身的纹理信息。5. 实验对比与调参经验从能出图到出好图5.1 主观评价先看目标再看背景最后看边缘评估融合效果第一步永远是肉眼观察。我自己的判断顺序是先看红外目标区域是否保持了足够高的亮度——如果融合图里原本红外的亮点变得灰蒙蒙说明低频融合权重出了问题然后看可见光的背景纹理比如树叶、栏杆、建筑外墙的细节是否清晰——如果这些区域糊成一片说明高频融合规则过于保守最后看目标与背景的交界处有没有光晕或拼接痕迹——如果有多半是权重图没有平滑到位。一个容易犯的错误是只看整体效果。融合图像整体看起来不错不代表局部没问题。我习惯把融合图和两幅源图并排放在一起用imshowimtool放大到100%逐个区域对比。很多细节问题在小比例缩略图里根本看不出来放大后无所遁形。5.2 客观指标信息熵、平均梯度、空间频率怎么读主观评价有局限还得靠数字说话。我常用的客观指标有四个各有侧重信息熵Entropy反映图像携带的信息量值越高说明灰度分布越丰富。但这个指标有个陷阱噪声多也熵高。所以信息熵只能配合主观评价一起看单独拿来比较两幅融合图很容易得出噪声大的更好这种错误结论。平均梯度Average Gradient衡量图像细节反差程度值越高说明边缘越锐利。它是比较不同融合方法在细节保留上最直观的指标。但同样它也不区分真实边缘和噪声。空间频率Spatial Frequency和平均梯度类似但更强调水平和垂直方向的频率成分对于评估方向性纹理的保留效果更敏感。空间频率由行频率和列频率的均方根合成计算简单在Matlab里十几行代码就能搞定。标准差Standard Deviation反映图像整体的对比度值越高说明灰度范围拉伸越大。这个指标在评估低频融合效果时非常有用——如果融合后的图像整体过暗或过亮标准差会明显偏低。我实测下来这套方法在平均梯度和空间频率上比传统拉普拉斯金字塔融合高出一截说明高频细节保留更好信息熵与基于小波的方法接近但视觉上的伪影更少。当然具体数值跟测试图像有很大关系每个人跑出来的结果可能不一样这里的关键是理解指标背后的意义而不是死记数值。5.3 调参踩坑记录五个容易翻车的地方第一个坑是数据类型。imread读进来是uint8直接丢进滤镜函数里计算会出现各种奇怪的数值溢出最典型的症状是结果图一片惨白。处理办法是进管线之前先im2double归一化到[0,1]融合完成后再im2uint8转回否则后面的imshow显示会异常。第二个坑是尺寸对齐。红外和可见光相机如果物理分辨率不同两路图像尺寸就不一样。金字塔分解时如果两路图像的尺寸不一致融合函数里逐层对应时会报错。解决方案是在主脚本里先统一尺寸if ~isequal(size(img_ir), size(img_vis)) img_vis imresize(img_vis, size(img_ir), bilinear); end这里我推荐以红外图像为基准缩放可见光因为红外图像的分辨率本身就低往上放大可见光不会造成额外的信息丢失。第三个坑是分解层数过多。我把可见光的分解层数从5层调到6层准备测试时最底层的残差图已经缩到了原图的1/64尺寸只有几十个像素。重建时上采样误差逐层累积结果出现明显的块状伪影。后面我把层数控制在5层以内问题消失。第四个坑是引导滤波的计算时间。imguidedfilter在1024×768的图像上5×5窗口大概需要0.1秒但如果你把窗口改成15×15时间可能直接翻到0.5秒以上。如果你用双边滤波替代更慢。批量处理大批量图像时这个时间成本不可忽略。我的建议是训练/实验阶段用3×3窗口加速最终出图再用5×5。第五个坑是最让人头疼的归一化范围。红外图像和可见光图像的灰度范围差别很大红外的目标区域灰度可能集中在0.8~0.9可见光整体可能只有0.1~0.4。如果不在分解前做各自的直方图均衡化或者对比度拉伸融合结果会出现红外过曝或可见光过暗的失衡。我实测下来对红外图像做一次简单的对比度拉伸imadjust把灰度范围线性拉到[0,1]就能显著改善融合图的视觉均衡性。还有一个小tips不同的输入图像对参数的敏感度不一样。白天场景和夜间场景融合参数应该分开调。如果你的数据集中同时有白天和夜间的图像对建议根据光照情况做判定分组使用不同的参数。一开始我是全局同一套参数结果白天图像融合后细节丢失后来分开调两边效果都稳了。6. 最后分享一个提升融合锐度的小技巧前面说的都是常规流程最后补一个我在调试中摸索出来的小技巧不算多复杂但对融合图像的锐度提升很有帮助。在做完金字塔重建、得到初步的融合图像之后可以对融合结果做一个微量的高频增强。具体做法是把融合图像做一次拉普拉斯金字塔分解只分解1层把得到的高频细节层乘以一个0.2~0.3的增益系数再加回原图。% 锐化增强 h fspecial(laplacian, 0.2); sharpened fused - imfilter(fused, h, replicate);这个操作等价于轻度锐化滤波器能进一步强调融合图像中的边缘细节。注意增益别太大超过0.5会引入明显的过冲现象边缘周围出现白色光圈反而得不偿失。这个技巧对整体信息熵、平均梯度指标也有小幅提升算是个免费的加分项。如果想控制变量发论文建议在实验中只把它作为后处理步骤列出不要混在主方法的消融实验里不然审稿人容易提出疑问。以上就是这套基于新型金字塔滤波器的非对称自适应多尺度分解方法的全部复现过程。从金字塔原理到非对称分解逻辑再到融合规则设计、Matlab实现和调参技巧核心就一句话知道两路图像的差在哪里就针对这个差异去设计不对称的处理策略。融合的效果提升从来不是靠单一技巧而是靠每一个环节都比传统方法多想一步。
返回列表