图像融合评估指标全解析:从PSNR到QAB/F的Python实现
简介面向图像融合与质量评价研究者提供一套Python评估指标工具包覆盖信息熵、空间频率、标准差、峰值信噪比、均方误差、互信息、视觉保真度、平均梯度、相关系数、差异相关和、Qabf、Nabf、SSIM与MS-SSIM等常见融合指标整包实现可直接调用。资源共540个文件以504张测试图像、9个核心Python脚本及配套配置文件为主压缩包约123.55MB指标脚本按模块组织便于按需扩展。已有5389人学习下载适合高校图像处理课程设计、论文实验对比及算法开发中需要统一指标评估的Python使用者。代码支持单幅图像、单个算法与多算法批量评估结果可写入Excel能显著降低实验阶段指标计算与结果整理的重复工作量。1. 图像融合评估指标先有尺子再谈融合效果跑完一版多聚焦融合算法肉眼看着边缘清楚、背景干净可一到写实验对比表就卡住检测任务有 mAP分割有 mIoU图像融合的输入是两张图、输出还是一张图既没有明确的损失函数也没有现成的 ground truth凭什么说明这版比上一版好这是很多做图像融合的人第一轮就会撞上的墙。所谓图像融合评估指标就是为这种“目标函数缺失”场景准备的一把客观尺子而且用 Python 实现并不复杂一个带 numpy 的环境就能跑通大部分常用指标不需要搭重框架。这套体系分有参考和无参考两大阵营绝大多数真实融合任务都落在无参考阵营的射程里。本文写给三类人想在融合结果上补一张正经指标表的研究者、要在多源图像增强方案里做指标验收的工程师以及刚进图像融合、还不清楚 PSNR、熵、QAB/F 这些名字背后各自衡量什么的新手。下面直接按“指标选型 → Python 实现 → 踩坑 → 落地技巧”的顺序推进。2. 评估指标的两个阵营有参考和无参考2.1 有参考指标什么时候才有“标准答案”有参考指标的前提是存在一张理想结果图也就是 ground truth通常用 ref 命名。这个前提在两类任务里成立一类是模拟融合实验把干净图像做模糊或加噪处理再让融合算法从退化的源图里把原图“拼”回来此时原图就是真值另一类是多聚焦融合图像传感器在同一场景下对不同焦平面成像分别清晰而理想的全清晰图像可以作为参考。但更常见的业务场景比如红外与可见光融合、医学多模态融合、遥感多光谱与全色融合根本不存在一张“标准答案”图。红外图像提供热辐射信息可见光提供纹理颜色信息融合的目标是把两种模态的信息互补进一张图里这张图既不是红外原图也不是可见光原图更不是两者的像素平均。强行用有参考指标去评估这类任务只能人为构造一张参考图常见做法是把两种源图加权平均后当作 ref再用 PSNR 和 SSIM 量融合图与它的差异。这个做法不是完全不能用但要知道它的逻辑前提很弱加权平均不是标准答案只是一个人为基线测出来的是“融合结果离这个基线有多远”而不是“融合结果有多好”。我给融合项目配评估方案时通常先问一个问题这个场景下有没有一个从业者公认的“理想输出”有才把 PSNR/SSIM 当作正式指标没有它们只能作为趋势参考绝不能写进验收依据。很多人把 PSNR 当作万能指标到处套这是最典型的概念错位。2.2 无参考指标融合评估的真正主力无参考指标不看真值图只从融合图本身、或者从“融合图 源图”的组合里提取统计特征判断融合质量。这里有一个被忽略的重要细分无参考不等于什么都不输入。按输入依赖可以分成两类仅需要融合图的指标比如信息熵、标准差、空间频率、平均梯度。它们衡量的是融合图自身的统计特性包括信息量、对比度、清晰度、边缘锐利程度。需要融合图与源图联合计算的指标比如互信息和 QAB/F。它们衡量的是融合结果从各源图里继承了多少信息、保留了多少边缘结构。这个区分直接影响你写代码时的函数签名。配评估套装时第一类指标回答“单看这张图质量如何”第二类回答“这张图有没有把源的优点保留下来”。两类都该有只测第一类会出现一个很滑稽的结果把一张纯噪声图放进去熵和标准差往往都很高但拿互信息和 QAB/F 一测就暴露了——它跟源图毫无关系。我在实际项目中会把无参考指标按“保真类”和“结构类”分开看。保真类用互信息做主要参考结构类用 QAB/F 做主要参考单图统计类作为辅助参考。这样的组合方式比只看某一项稳得多也不会被单个指标带偏。2.3 指标速览表输入依赖、取值范围与衡量维度指标需要输入取值范围衡量维度方向PSNR融合图 参考图理论上 0~∞常见 20~50 dB像素级重构精度越大越好SSIM融合图 参考图-1~1通常 0~1亮度/对比度/结构相似度越大越好信息熵仅融合图0~88 bit 灰度图信息丰富度越大越好标准差仅融合图0~128 量级对比度/动态范围越大越好空间频率仅融合图0~∞图像细节总量越大越好平均梯度仅融合图0~∞边缘锐利程度越大越好互信息 MI融合图 一张源图0~∞常见 0~2融合图与源图的信息关联越大越好QAB/F融合图 两张源图0~1从源图到融合图的边缘保留度越大越好选型方法论就一句没有哪个指标能同时覆盖所有判断维度评估套装至少 4 项起步。面向人眼观察类应用核心看 QAB/F 和平均梯度面向检测识别等下游任务核心看互信息和熵有真值可用的场景再补 PSNR 和 SSIM。物理意义比数值本身重要任何单指标数值都不能代表融合质量的全貌。3. 用 Python 实现有参考评估PSNR 与 SSIM3.1 PSNR三行代码但藏着一个 uint8 陷阱PSNR 的全称是峰值信噪比核心逻辑非常朴素两张图逐像素求误差误差越小、信噪比越高。公式写成 Python 只需要几行但有个很容易翻车的细节uint8 类型直接相减会发生无符号溢出。import numpy as np def psnr(fused, ref, max_value255.0): 有参考指标峰值信噪比单位 dB越大越好。 fused : 融合图形状 (H, W) ref : 参考图真值图形状必须与 fused 完全一致 max_value : 像素最大值uint8 图传 255.0float 归一化图传 1.0 # 先转 float64 再相减避免 uint8 无符号溢出 fused fused.astype(np.float64) ref ref.astype(np.float64) mse np.mean((fused - ref) ** 2) if mse 1e-10: # 两张图完全一致时 MSE 为 0除零无意义按无穷大处理 return float(inf) return 10.0 * np.log10(max_value * max_value / mse)这段代码需要注意两个点。第一是 astype 的位置必须在相减之前完成uint8 的取值范围是 0~255两个 uint8 相减结果仍然是 uint8小的减大的会绕回 255 附近算出来的 MSE 完全失真。第二是 max_value 参数要与输入数据范围匹配常见的错误是输入 0~1 归一化图却传 255.0导致 PSNR 整体虚高约 48 dB横向对比时全部失真。PSNR 对像素级误差敏感但它并不感知空间结构把一张图平移一个像素再跟原图比MSE 会暴涨PSNR 骤降可人眼看这两张图几乎没区别。所以在融合评估里PSNR 不能作为唯一依据它的角色更多是“量化重构误差”而不是“量化视觉质量”。3.2 SSIM用高斯窗口算结构相似度SSIM 的完整中文名是结构相似性指标它把图像质量拆成亮度、对比度、结构三个分量用滑动窗口逐区域比较最后返回全图均值。相比 PSNR 的逐像素比较SSIM 更接近人眼对局部结构的感知。import numpy as np from scipy.ndimage import convolve def ssim(fused, ref, radius4, c10.01**2, c20.03**2): 有参考指标结构相似度通常落在 0~1越大越好。 fused / ref : 输入图形状一致 radius : 高斯窗口半径默认 4 对应 9x9 窗口 c1 / c2 : 稳定常数避免分母接近 0 fused fused.astype(np.float64) ref ref.astype(np.float64) def gaussian_window(size, sigma1.5): axis np.arange(-(size // 2), size // 2 1) kernel_1d np.exp(-(axis ** 2) / (2 * sigma ** 2)) kernel_2d np.outer(kernel_1d, kernel_1d) return kernel_2d / kernel_2d.sum() win gaussian_window(2 * radius 1) mu1 convolve(fused, win, modereflect) mu2 convolve(ref, win, modereflect) mu1_sq mu1 * mu1 mu2_sq mu2 * mu2 mu12 mu1 * mu2 sigma1_sq convolve(fused * fused, win, modereflect) - mu1_sq sigma2_sq convolve(ref * ref, win, modereflect) - mu2_sq sigma12 convolve(fused * ref, win, modereflect) - mu12 ssim_map ((2 * mu12 c1) * (2 * sigma12 c2)) / ( (mu1_sq mu2_sq c1) * (sigma1_sq sigma2_sq c2) ) return float(ssim_map.mean())实现逻辑是先用高斯窗口分别求融合图与参考图的局部均值、局部方差、局部协方差再代入 SSIM 公式逐像素生成一张质量图最后取均值。这里 scipy.ndimage.convolve 的 modereflect 是为了处理图像边缘时不引入黑色边框如果不想依赖 scipy也可以用 cv2.GaussianBlur 替代这个卷积效果接近。radius 这个参数值得留意。默认 4 用的是 9x9 窗口在 512x512 的图上算得比较稳如果源图本身只有几十像素宽比如某些遥感切片窗口会占到图像比例过大建议把 radius 降到 2。c1、c2 的默认值来自 SSIM 原论文公式数值范围是相对 0~255 灰度设计的如果输入是 0~1 归一化图这两个常数要同步缩小 255 倍否则 SSIM 会对细微结构差异不敏感。3.3 有参考指标的边界什么场景真的能用有参考指标在融合领域的应用边界非常清晰只有能拿到真值图的场景才适合做主指标。多聚焦融合可以用全清晰图做 ref因为理论上存在一张所有物体都清晰的理想图模拟退化实验也可以因为退化前的图就是标准答案。红外与可见光融合、医学图像融合这类场景里给融合图人工造一张参考图的做法我一般不建议写进正式结论。造出来的 ref 本身带有主观假设指标反映的是“离这个假设有多远”而不是“融合质量有多高”。如果实验设计里必须要有参考指标来对比不同方法我通常会多做一组合成数据实验把红外图的灰度结构当作真值、把可见光图当作纹理补充构造已知答案的模拟源图再用 PSNR/SSIM 验证算法正确性。真实图像上用无参考指标合成图像上用有参考指标两者分开评估、互不混淆这个习惯能避免很多汇报现场被质疑的尴尬。4. 用 Python 实现无参考评估熵、互信息与 QAB/F4.1 信息熵与标准差融合图本身的信息量与对比度信息熵衡量图像灰度分布的离散程度分布越均匀、熵越高说明图像携带的信息越丰富。这是无参考评估里最常用、也最容易写错的一个指标。import numpy as np def entropy(image, levels256): 无参考指标信息熵单位 bit理论最大值 log2(levels)。 image : 灰度融合图形状 (H, W) levels : 灰度级数uint8 图传 256float 归一化图需要先处理 if image.dtype np.uint8: img image.astype(np.uint8) else: # float 归一化图先放大到 0~255 再取整直接截断会全部坍缩到 0 img np.clip(np.round(image * 255.0), 0, 255).astype(np.uint8) hist np.bincount(img.ravel(), minlengthlevels)[:levels].astype(np.float64) prob hist / hist.sum() prob prob[prob 0] # 去掉概率为 0 的灰度级避免 log(0) return float(-np.sum(prob * np.log2(prob)))最关键的一行是 float 图的预处理np.round(image * 255.0) 之后再 astype(np.uint8)。如果直接对 0~1 的 float 图做 astype(np.uint8)所有小于 0.5 的像素都变成 0整个图坍缩成一个灰度值熵直接变成 0这个结果在论文里出现会非常尴尬。这个细节也是后续避坑章节要重点讲的现象。标准差这个指标简单到不需要封装函数np.std(image) 一行就够但要注意需要转 float 再算。标准差衡量灰度值的离散程度数值越大说明图像对比度越强、明暗层次越丰富。它的局限也很明显一张对比度拉满的椒盐噪声图标准差极高但视觉质量很差所以标准差只能作为辅助参考不能单独下结论。4.2 互信息 MI融合图与源图的“信息继承度”互信息衡量两个随机变量之间的统计相关性在图像融合里通常这样理解融合图跟某张源图之间的 MI 越大说明融合图从这张源图中保留的信息越多。标准做法是分别计算融合图与各源图的 MI两张源图各出一个值结论里可以分开报。import numpy as np def mutual_information(source, fused, levels256): 无参考指标源图与融合图的互信息越大代表信息继承度越高。 source : 任选一张源图 fused : 融合图 levels : 灰度量化级数 def _to_uint8(img): if img.dtype np.uint8: return img.copy() return np.clip(np.round(img * 255.0), 0, 255).astype(np.uint8) s _to_uint8(source) f _to_uint8(fused) # 二维联合直方图统计同一位置灰度组合出现的频次 joint_hist, _, _ np.histogram2d( s.ravel(), f.ravel(), binslevels, range[[0, levels], [0, levels]] ) p_joint joint_hist / joint_hist.sum() # 联合概率 p_s p_joint.sum(axis1, keepdimsTrue) # 源图边缘概率 p_f p_joint.sum(axis0, keepdimsTrue) # 融合图边缘概率 denom p_s * p_f # 独立假设下的联合概率 valid (p_joint 0) (denom 0) # 跳过无观测的位置 with np.errstate(divideignore, invalidignore): log_ratio np.log2(p_joint / denom) log_ratio np.where(valid, log_ratio, 0.0) return float(np.sum(p_joint * log_ratio))这段实现里有一个需要重点说明的设计denom 出现 0 时np.log2 会产生除零警告所以先用 valid 掩码把非法位置过滤掉参与累加的全是有效观测。levels 参数影响联合直方图的粒度256 级在 512x512 图像上每个灰度组合平均样本不足 4 个直方图偏稀疏有些论文改用 64 级量化结果更稳定。我个人的习惯是评估时统一用 128 级比 256 级噪声小、比 64 级信息量足但要注意整套实验保持同一参数。互信息的语义和熵不同熵只看融合图本身信息量哪怕全是噪声也可能给出高值MI 则要求融合图与源图有统计关联。把两张完全无关的图像放一起算 MI结果会接近 0这正是它的价值——检验融合过程的“保真性”。4.3 QAB/F最接近人眼判断的梯度保留指标QAB/F 全称是“基于梯度信息的融合质量指标”它度量融合图到底保留了多少来自源图的边缘信息。人眼对图像质量最敏感的部分就是边缘所以 QAB/F 在融合评估里被视为最接近主观观察的客观指标取值范围 0~1越高越好。实现思路分四步第一步对源图 A、源图 B、融合图 F 分别做 4 方向 Sobel 卷积得到每个像素的边缘强度和边缘方向第二步计算融合图相对各源图的强度保留度和方向保留度第三步将两者合成像素级保留度第四步按源图边缘强度加权求和得到全局 QAB/F。import numpy as np from scipy.ndimage import convolve def qabf(source_a, source_b, fused, K2.0, sigma1.0): 无参考指标QAB/F 梯度保留度0~1越大越好。 source_a / source_b : 两张源图灰度图与 fused 同尺寸 fused : 融合图 K : sigmoid 斜率控制保留度随梯度变化的敏感程度 sigma : sigmoid 阈值边缘强度比超过此值才算“保留住了” kernels [ np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]), # 水平 np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]), # 垂直 np.array([[0, 1, 2], [-1, 0, 1], [-2, -1, 0]]), # 主对角 np.array([[-2, -1, 0], [-1, 0, 1], [0, 1, 2]]), # 副对角 ] def _gradient(img): # 对 4 个方向分别卷积取响应绝对值最大的方向作为该像素边缘 resp [np.abs(convolve(img, k, modemirror)) for k in kernels] g np.maximum.reduce(resp) alpha np.argmax(resp, axis0) return g, alpha g_a, a_a _gradient(source_a.astype(np.float64)) g_b, a_b _gradient(source_b.astype(np.float64)) g_f, a_f _gradient(fused.astype(np.float64)) def _retention(g_src, a_src, g_fus, a_fus): # 边缘强度保留比源边缘强则看融合保留多少反之说明融合引入多余边缘 g_ratio np.where( g_src g_fus, g_fus / np.maximum(g_src, 1e-10), g_src / np.maximum(g_fus, 1e-10), ) # 方向差取 0~90 度范围90 度视为完全不保留 diff_hat (a_src - a_fus) % 4 diff_hat np.minimum(diff_hat, 4 - diff_hat) xi 1.0 - diff_hat * 45.0 / 90.0 q_g 1.0 / (1.0 np.exp(-K * (g_ratio - sigma))) q_alpha 1.0 / (1.0 np.exp(-K * (xi - sigma))) return q_g * q_alpha q_af _retention(g_a, a_a, g_f, a_f) q_bf _retention(g_b, a_b, g_f, a_f) w_a, w_b g_a, g_b denom np.sum(w_a w_b) 1e-10 return float(np.sum(w_a * q_af w_b * q_bf) / denom)代码中 4 个 Sobel 核分别对应水平、垂直、两条对角线方向这是原版思路图像边缘不只有横竖两种走向斜向边缘在单一方向 Sobel 下会漏检。梯度强度取 4 个方向响应的最大值方向取最大值对应的核编号这样每个边缘像素都获得一个离散化的方向值。_gradient 返回的 alpha 取值范围是 0~3计算方向差时用取模运算处理角度环回0 和 3 之间真实角度差只有 45 度用直接相减会得到 3。方向差再归一化到 0~190 度正交的极端情况保留度为 0。sigmoid 的两个参数 K 和 sigma 是 QAB/F 里最容易被忽略的关键。sigma 默认 1.0表示只有边缘强度保留比超过 1.0 时保留度为 0.5 以上K 控制这个过渡带的陡峭程度。需要强烈提醒的是这套参数在你自己项目内部是自洽的但不同论文、不同公开实现里 sigmoid 的形态差异极大有些版本甚至直接用 min/max 比值做保留度而不做 sigmoid导致同一个融合方法在不同实现下 QAB/F 可能差出 0.2 以上。所以 QAB/F 的横向对比必须限定在同一个代码库内进行跨论文对比数值没有意义。4.4 空间频率与平均梯度清晰度的两个快速探针空间频率衡量图像整体细节丰富程度平均梯度衡量边缘锐利程度。两个指标都只依赖融合图本身计算量小适合在批量评估里作第一层筛选。import numpy as np def spatial_frequency(image): 无参考指标空间频率 SF值越大细节总量越多。 img image.astype(np.float64) h, w img.shape row_diff img[:, 1:] - img[:, :-1] col_diff img[1:, :] - img[:-1, :] rf np.sqrt(np.sum(row_diff ** 2) / (h * w)) cf np.sqrt(np.sum(col_diff ** 2) / (h * w)) return float(np.sqrt(rf * rf cf * cf)) def average_gradient(image): 无参考指标平均梯度 AG值越大边缘越锐利。 img image.astype(np.float64) dx img[1:, :] - img[:-1, :] # 垂直差分形状 (H-1, W) dy img[:, 1:] - img[:, :-1] # 水平差分形状 (H, W-1) gx dx[:, :-1] # 对齐到 (H-1, W-1) gy dy[:-1, :] return float(np.mean(np.sqrt((gx ** 2 gy ** 2) / 2.0)))两个指标的逻辑区别值得说明空间频率关注差分的大小累计整幅图细节越密数值越高所以它对纹理丰富的区域非常敏感平均梯度把差分逐像素化再取平均更看重每个像素位置上的局部变化强度。实际使用中空间频率容易被图像本身的亮部和纹理带偏而平均梯度相对均匀。两张图一个 SF 高一个 AG 高时意味着前者整体细节丰富但边缘不够聚拢后者锐利但纹理总量少具体选哪个需要回到应用目标去判断。5. 图像融合评估避坑五个最容易翻车的细节5.1 坑一uint8 图直接相减PSNR 出现几百甚至无穷大现象融合图和参考图肉眼看着差不多但 PSNR 算出来超过 100 dB或者出现明显的正负震荡。原因uint8 是无符号 8 位整型取值范围 0~255。两张 uint8 图直接相减时128 - 200 不会得到 -72而是溢出成 184MSE 和真实误差完全脱节。如果刚好两张图在某个区域像素值完全相等误差为 0再乘平方就会得到异常偏大的 PSNR。解决所有涉及差值的计算第一步永远先 astype(np.float64)。PSNR、SSIM、SF、AG 都适用这条规则。批量评估前加一个断言assert fused.dtype ref.dtypedtype 不一致直接报错比在结果表里排查异常值省力得多。5.2 坑二float 归一化图直接转 uint8熵和 MI 集体塌缩现象信息熵输出 0.0 或者严重偏低互信息也异常小但融合图肉眼看着色彩层次很正常。原因0~1 的 float 图直接调用 astype(np.uint8)所有小于 0.5 的值都会截断成 0大于等于 0.5 的截断成 1。整幅图被压缩成两三个灰度级直方图几乎只剩一个峰值熵当然趋近 0。解决float 图转 uint8 必须经过缩放np.clip(np.round(img * 255.0), 0, 255).astype(np.uint8)。同样的问题也会出现在计算联合直方图时所以 MI 函数内部统一封了一个 _to_uint8 做兜底。把输入预处理收敛到指标函数内部而不是依赖调用方每次手写能显著减少这类低级错误。5.3 坑三QAB/F 参数乱设同一个融合方法跑出完全不同的结论现象用网上某个实现跑 QAB/F融合图 A 比 B 高换一套实现结果反过来。两个结论都晒在实验报告里自己都不知道该信谁。原因QAB/F 的 sigmoid 公式在不同版本里有 K 和 sigma 的差异有的实现还把 K 固定成 10、sigma 固定成 0有的则用 1 和 1再加上是否做方向差取模、是否加权求和等细节不同最终数值差出 0.2 都不奇怪。这不是算法错了而是参数体系不一致。解决从项目第一天就把 QAB/F 的参数写死在配置里例如 K2.0、sigma1.0并且在文档里标注清楚整套实验、所有对比方法都用同一个函数、同一组参数。发表或汇报时必须写明 QAB/F 的实现细节和参数注明是“本代码库内自洽对比”。想跨论文复现别人的数值基本不可行。5.4 坑四指标结论互相打架不知道以哪个为准现象融合方法 X 的熵和 MI 比方法 Y 高但 QAB/F 和平均梯度比 Y 低。实验结论怎么写都不对。原因熵衡量信息量QAB/F 衡量边缘保留度两者本来就不是同一种判断。融合图细节多但边缘组织差的时候熵会高QAB/F 会低反过来边缘保留得好但信息量不足熵也会低。指标互相矛盾不是 bug而是因为它们在看不同的维度。解决先定主指标再定辅助指标。评估目标是“人眼看得舒服”主指标用 QAB/F、辅助用平均梯度和熵目标是“给下游检测算法喂数据”主指标用 MI、辅助用空间频率。主指标相同方向时再参考辅助指标不要拿多个指标投票表决那会把问题搞得更乱。5.5 坑五边界处理不一致批量评估结果系统性偏移现象同一组数据跑两遍评估结果略有差异用小尺寸测试图时差异更明显融合方法排序偶尔还会变化。原因卷积类操作在图像边缘需要确定越界像素怎么处理modereflect、mirror、constant 三种模式在边缘处产生完全不同的值。SSIM 和 QAB/F 都涉及卷积边界模式不一致会让边缘区域的指标统计产生系统性偏差。图像越小的数据集边缘像素占比越高偏差越大。解决整个评估代码库统一使用 modemirror 或 modereflect禁止混用。批量评估脚本里加一个全局常量比如 BORDER_MODE mirror所有卷积调用都引用它。另外把测试图像集裁剪成整齐尺寸再做评估避免出现奇数尺寸图像在差分计算里多一行少一列的情况。6. 指标组合拳用一套评估函数快速定位融合算法的短板评估不是把指标打印出来就结束而是要用指标反向指导算法调优。我会把所有常用指标封装成一个统一入口输入两张源图、一张融合图一次性返回完整指标字典避免在实验里反复复制粘贴代码。import numpy as np def evaluate_fusion(source_a, source_b, fused, refNone): 一键输出融合评估指标集。 ref 为 None 时自动跳过 PSNR/SSIM适合无真值的融合场景。 返回 dictkey 为指标名value 为浮点数值。 metrics { entropy: entropy(fused), std: float(np.std(fused.astype(np.float64))), sf: spatial_frequency(fused), ag: average_gradient(fused), mi_with_a: mutual_information(source_a, fused), mi_with_b: mutual_information(source_b, fused), qabf: qabf(source_a, source_b, fused), } if ref is not None: metrics[psnr] psnr(fused, ref) metrics[ssim] ssim(fused, ref) return metrics拿到这个字典后我会画一张简单的对比表来定位问题。假设两种融合方法 A 和 B 的读数如下指标方法 A方法 B判断倾向熵7.17.4B 信息量略高互信息(A)1.20.8A 更保真红外源互信息(B)1.01.3B 更保真可见光源QAB/F0.680.61A 边缘保留更好平均梯度4235A 更锐利这个组合说明方法 B 靠抬高整体信息量赢在熵指标上但边缘保留度输给了 A且在两张源图的 MI 上偏向明显方法 A 是保守型融合边缘组织好但引入的新信息有限。如果项目目标是侦查类视觉任务我会保留 A 的梯度优势、补上 B 在弱纹理区域的信息补充能力如果目标是红外目标检测A 的强边缘反而更关键。指标本身不告诉你答案但能精确指出算法在哪个维度偏科。我最后养成的习惯是每跑一批融合实验先自查三件事——所有图是否统一转 float64、float 图转 uint8 是否先缩放、QAB/F 参数是否同一套。这三件事全对再谈指标对比。指标数值是拿来辅助判断的不是拿来给报告凑数的参数和口径不统一时数值越精确越危险。希望这篇把图像融合评估这条路上的沟沟坎坎讲清楚了能帮你少走几趟弯路。本文还有配套的精品资源点击获取

相关新闻

协作频谱感知中的Pietra-Ricci指数检测器:Matlab融合实现解析

协作频谱感知中的Pietra-Ricci指数检测器:Matlab融合实现解析

前一阵子帮一个团队调试协作频谱感知的仿真平台,他们把单节点能量检测器换成了基于分布形貌的盲检测器之后,整个系统的虚警率在高噪声不确定度环境下稳定了不少。这个检测器就是大家常说的 Pietra–Ricci 指数检测器。这次我把自己在 Matlab 里实现“集中…

2026/10/13 4:20:04 阅读更多 →
人体感应芯片PIR模块驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

人体感应芯片PIR模块驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】

I2C 上那串芯片告一段落。今天换一根高低电平——人体感应。脚号不能猜,悬空会恒报有人。这一章不谈 I2C,也不谈 UART。人体感应模块对外就一根数字脚:有人经过,电平翻一下;没人,电平待在另一边。软件上它就…

2026/10/13 4:20:04 阅读更多 →
六杆急回机构运动学与动力学分析:从建模到Matlab仿真全流程

六杆急回机构运动学与动力学分析:从建模到Matlab仿真全流程

做机构分析这些年,遇到最多的情况就是:四杆机构人人都能算,曲柄摇杆、曲柄滑块讲得滚瓜烂熟,但一碰到六杆机构就抓瞎。市面上教材里对六杆快速回归机构的完整推导少之又少,公式绕、坐标多、代码更是没人贴。偏偏这东西…

2026/10/13 4:20:04 阅读更多 →

最新新闻

Android Socket编程从阻塞到NIO:原理、实践与性能调优

Android Socket编程从阻塞到NIO:原理、实践与性能调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:44:37 阅读更多 →
AHP层次分析法实战指南:多目标决策的量化落地方法

AHP层次分析法实战指南:多目标决策的量化落地方法

1. 这不是数学课,是解决“到底该听谁的”问题的实战工具你有没有遇到过这种场景:团队要选一个新办公地点,大家各执一词——行政说交通便利最重要,财务强调租金成本得压死线,技术部坚持网络稳定是生命线,而老…

2026/10/13 5:44:37 阅读更多 →
Windows下用WSL2+PyCharm搭建Redash开发环境

Windows下用WSL2+PyCharm搭建Redash开发环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:44:37 阅读更多 →
K8s离线部署flannel镜像包:从拉取导出到导入验证的完整避坑指南

K8s离线部署flannel镜像包:从拉取导出到导入验证的完整避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:44:37 阅读更多 →
React生命周期深度解析:从类组件到Hooks的迁移实战

React生命周期深度解析:从类组件到Hooks的迁移实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:44:37 阅读更多 →
ICE中间件环境搭建与Demo实战:跨语言通信避坑指南

ICE中间件环境搭建与Demo实战:跨语言通信避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:43:37 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →