
简介这是基于Matlab实现的图像融合质量评估工具仓库面向计算机、电子信息工程、数学等专业的学生与研究者可用于课程设计、期末大作业及毕业设计中的融合效果量化对比。仓库封装了EN、CE、MI、FMI_pixel、FMI_dct、FMI_w、PSNR、MSSSIM、RMSE、SF、SD、方差、EI、AG、VIF、Qcb、Qabf、CC、SCD、Nabf、Qcv等二十余项常见评估指标覆盖信息熵、互信息、结构相似性、边缘梯度、视觉保真等多个维度。代码采用参数化编程思路各指标计算模块相对独立注释明细便于按需调用和扩展。资源共31个文件以24个m脚本为主体附赠案例数据可直接运行另有3张效果示意图、2个文本说明、1个Markdown说明及1份Excel表格压缩包仅188KB轻量易用。已有121人学习下载适合需要快速搭建图像融合评价实验环境、批量计算多指标并对比结果的高校学生与科研人员。1. 图像融合评估为什么指标比算法更容易骗人融合结果好不好肉眼说了不算指标说了也不算——这是图像融合评估领域最容易被忽略的事实。把可见光和红外图像融合后到底保留了多少边缘细节、有没有把噪声当特征放大只靠“看”是得不到可复现结论的。Qabf、CC、SCD、Nabf、Qcv 这组指标在地面遥感、医学影像、多曝光合成等方向的对比实验里几乎是标配裁判它们分别从梯度保真、整体相关、差分互补、噪声引入、视觉保真这几个维度把一幅融合图像量化成一张分数表。这篇笔记把这套评估体系的物理语义拆开给出可复现的 Python 实现与参数说明再列出使用中常见的高频翻车点。哪怕你手里只有一个来源不明的 .rar 工具包也能据此判断里面每个函数到底在算什么。2. 五个指标的含义与选择逻辑Qabf、CC、SCD、Nabf、Qcv 都在测什么2.1 梯度域的两个指标Qabf 与 Nabf 为什么必须成对看Qabf 来源于经典的 Xydeas-Petrovic 边缘信息保留度量思路很直接先从源图和融合图中分别算出每个像素的边缘强度与边缘方向再逐点比较融合图相对于源图在梯度幅度和方向上的保持程度。最后用源图的边缘显著性做加权平均得到 0 到 1 之间的分数越接近 1 说明融合结果把源图里肉眼关心的轮廓、纹理边界保留得越完整。Nabf 在不少仓库里被命名为“基于噪声的融合质量指标”核心思想却高度一致它度量融合结果在边缘位置上相对源图出现了多少额外差异。常见实现是把融合图和源图逐像素做差再用源图的边缘强度做加权得到的数值越小越好。如果一个融合算法把高频细节“增强”过头视觉上看似锐利Nabf 会立刻把这种伪影暴露出来。实际评测时两个指标必须一起看Qabf 高只能说明边缘保留好Nabf 高则说明这些“保留”里混入了源图没有的跳变单独拿任何一个当结论都很容易误判。这两个指标对图像的全局亮度不敏感但对几何对齐极其敏感。只要两幅图之间出现一个像素的偏移边缘位置就不重合梯度比较的数值会大幅下跌。因此它们适合在图像配准之后使用不适合用来评价未做对齐的原始多模态图像对。2.2 宏观相关性指标CC 为何简单却不可或缺CC 全称是 Correlation Coefficient计算融合图与每个源图之间的 Pearson 相关系数再取平均。值域在 -1 到 1 之间正常融合结果都在 0 以上。它衡量的是两幅图像在整体灰度结构上的线性相关程度对边缘细节不敏感但对全局亮度偏移非常敏感。这个指标看起来朴素却承担着其他指标替代不了的作用当融合算法把图像整体色调拉偏、或者把某个通道的均值搞乱时Qabf 和 SCD 可能依然表现平稳CC 一定先垮下来。再加上它计算成本极低适合在批量预处理阶段作为“体检指标”帮助快速筛掉结构性崩坏的融合结果。需要注意的是CC 追求的是“与源图相似”而融合的本质是“取两者之长”。如果某个融合结果完全退化成源图 A 的拷贝CC 也会很高所以它必须与 SCD、Qabf 联合使用不能单独当标准。2.3 SCD从差分里看互补信息是否真的被保留SCD 的全称是 Sum of the Correlation of Differences中文常叫差分相关性之和。它的构造非常巧妙设源图为 A、B融合图为 F先计算两个差分图D1 F - B D2 F - A如果融合图很好地保留了 A 中独有的信息那么 D1 应该在 A 独有结构的位置上有明显的响应因此 D1 与 A 的相关系数应该高同理D2 与 B 的相关系数应该高。最终 SCD 就是这两个相关系数之和。这个设计与 Qabf、CC 的视角完全不同它评估的是“互补信息”而不是“相似信息”。多模态融合里红外图里有可见光图没有的热目标可见光图里有红外图没有的纹理细节SCD 就是专门盯着这部分看的指标。若融合算法只是简单加权平均SCD 通常偏低若采用基于显著性或稀疏表示的融合规则SCD 往往有明显提升。使用时要特别注意差分的方向把 D1 和 D2 写反结果会从正相关变成负相关数字直接不可用。2.4 Qcv视觉保真指标家族与实现分歧Qcv 在不同工具包里的定义差异是五个指标中最大的。有的仓库把 Qcv 实现成视觉信息保真度框架下的分块指标有的则用局部梯度相似度或结构相似度做近似。共同点是它们都以人眼视觉系统的特性作为加权依据对高对比度边缘、显著性区域赋予更高权重对平坦区域降低权重。换句话说Qcv 衡量的是“融合结果在人类视觉重点区域上的保真程度”。在没有原始源码时合理的做法是实现一个带局部显著性权重的梯度相似度版本作为 Qcv 的近似替代。它满足视觉保真族指标的三条基本要求局部窗口运算、显著性加权、值域在 0 到 1。如果仓库里自带的 Qcv 定义与这个近似版本差别很大也不要慌张先看公式再谈对比否则指标之间根本没有可比性。2.5 指标搭配什么时候该重点看哪个指标侧重内容理想趋势典型适用场景Qabf边缘与梯度信息保真越高越好红外与可见光融合、多聚焦融合Nabf融合引入的噪声与伪影越低越好去噪类预处理、超分辨率融合CC整体灰度结构相关性越高越好批量预处理筛查、全局色调检查SCD差分域中的互补信息保持越高越好多模态异源图像、显著性融合规则对比Qcv视觉显著区域的保真度越高越好主观质量倾向明显、展示场景优先选指标时记住一个原则对比融合算法时至少同时在梯度域和差分域各选一个指标再搭配 CC 做全局兜底。只拿一个标榜“全面”的指标做结论在评审和论文返修阶段往往会被追问到很难收场。3. 用 Python 复现 Qabf、CC、SCD、Nabf、Qcv完整代码与参数说明3.1 环境约定与输入预处理这套实现只依赖 NumPy 和 SciPyPython 3.8 以上即可运行。统一约定所有输入为单通道灰度图尺寸一致像素数值先归一化到 [0,1]。先把公共的预处理函数写好。import numpy as np from scipy.ndimage import sobel, uniform_filter def _to_float_gray(img): 把任意常见输入统一成 [0,1] 的 float64 灰度图 img np.asarray(img) if img.ndim 3: img img.mean(axis2) # 三通道或 RGBA 直接取均值转灰度 img img.astype(np.float64) if img.max() 1.0: img img / float(img.max()) # 按全局最大值归一 return img def _check_shape(a, b, f): if not (a.shape b.shape f.shape): raise ValueError(源图与融合图尺寸必须一致: %s %s %s % (a.shape, b.shape, f.shape))这段代码解决了两类最常见的预处理问题一是三通道图忘了转灰度二是 uint8 取值 0-255 直接参与数值运算。归一化时必须先转 float64 再做除法否则整数除法会把 200/255 变成 0。尺寸检查建议放在所有指标计算入口处这样在多组图像批量评测时一旦某组数据有问题就能立刻报错而不是算出一堆无意义数字。3.2 Qabf 的完整实现与参数说明实现 Xydeas-Petrovic 度量时最核心的两个坑是边缘方向的周期折叠和 Sigmoid 参数的选择。下面给出可直接运行的版本。def _edge_strength_orientation(img): 返回边缘强度 g 与边缘方向 aa 的范围为 [-pi, pi] gx sobel(img, axis1) # 水平梯度 gy sobel(img, axis0) # 垂直梯度 g np.hypot(gx, gy) a np.arctan2(gy, gx) return g, a def _angle_diff(a1, a2): 计算两个方向角的最小差值并归一化到 [0,1] d np.mod(a1 - a2, np.pi) # 先折叠到 [0, pi) d np.where(d np.pi / 2, np.pi - d, d) # 边缘方向差取锐角 return 2.0 * d / np.pi def qabf(img_a, img_b, img_f, eps1e-10): gA, aA _edge_strength_orientation(img_a) gB, aB _edge_strength_orientation(img_b) gF, aF _edge_strength_orientation(img_f) # 相对边缘强度越接近 1 说明梯度幅度保持得越好 gAF np.minimum(gA, gF) / (np.maximum(gA, gF) eps) gBF np.minimum(gB, gF) / (np.maximum(gB, gF) eps) # 方向差归一化到 [0,1] aAF _angle_diff(aA, aF) aBF _angle_diff(aB, aF) # Xydeas-Petrovic 原始参数 Kg, sg -10, 0.5 Ka, sa -20, 0.75 QgAF 1.0 / (1.0 np.exp(-Kg * (gAF - sg))) QaAF 1.0 / (1.0 np.exp(-Ka * (aAF - sa))) QAF QgAF * QaAF QgBF 1.0 / (1.0 np.exp(-Kg * (gBF - sg))) QaBF 1.0 / (1.0 np.exp(-Ka * (aBF - sa))) QBF QgBF * QaBF wA gA # 边缘显著性作为权重 wB gB denominator np.sum(wA wB) eps return np.sum(QAF * wA QBF * wB) / denominator先解释_angle_diff为什么必须存在arctan2返回的角度范围是 [-π, π]而图像边缘的几何方向 0 与 π 其实是同一条线。如果直接做差并取绝对值一个 179 度一个 -179 度的两条边缘会被误判为方向差巨大实际上它们几乎平行。先折叠到 [0, π)再统一取锐角最后乘 2/π 归一化这个预处理是所有 Qabf 实现里最容易漏掉的一步。再看 Sigmoid 参数。Kg 取 -10、Ka 取 -20 是原文对人类视觉系统标定的结果强度差异在 0.5 附近开始明显影响视觉感知方向差异在 0.75 附近达到敏感阈值。实际使用时这两个参数基本不用改。如果想让指标对轻微退化更敏感可以适当加大 Ka 的绝对值代价是噪声也会被放大分数波动明显。权重 wA 直接用源图边缘强度意味着强边缘处的保真度对总分影响更大这也符合视觉显著性直觉。3.3 Nabf 的实现与加权方式Nabf 在这里实现为融合图与源图在边缘位置上的加权绝对差。数值越低说明融合结果在边缘处引入的异常跳变越少。def nabf(img_a, img_b, img_f, eps1e-10): gA, _ _edge_strength_orientation(img_a) gB, _ _edge_strength_orientation(img_b) diff_a np.abs(img_f - img_a) diff_b np.abs(img_f - img_b) numerator np.sum(diff_a * gA diff_b * gB) denominator np.sum(gA gB) eps return numerator / denominator这里的权重 gA、gB 与 Qabf 保持一致保证两个指标在同一套显著性体系下说话。diff 使用的是绝对值而不是平方目的是避免个别像素的大差异主导结果平方版本对离群点更敏感适合用来检测脉冲噪声但作为融合质量评估不够稳定。有个使用细节值得注意如果源图本身带有较强噪声Nabf 的基线值本身就不为零。此时可以把源图 A 当作“融合图”与源图 B 做一次 Nabf 计算得到的是系统噪声基线。评测融合算法时用融合结果的 Nabf 减去这个基线才是更公平的数值。3.4 CC 与 SCD 的实现def cc(img_a, img_b, img_f): corr_af np.corrcoef(img_a.ravel(), img_f.ravel())[0, 1] corr_bf np.corrcoef(img_b.ravel(), img_f.ravel())[0, 1] return 0.5 * (corr_af corr_bf) def scd(img_a, img_b, img_f): d1 img_f - img_b # 融合图相对 B 的差分理论上保留 A 的独有信息 d2 img_f - img_a # 融合图相对 A 的差分理论上保留 B 的独有信息 corr_d1_a np.corrcoef(d1.ravel(), img_a.ravel())[0, 1] corr_d2_b np.corrcoef(d2.ravel(), img_b.ravel())[0, 1] return corr_d1_a corr_d2_bCC 取两个相关系数的均值后取值范围仍在 [-1,1] 内便于跨实验比较。SCD 则不同它是两个相关系数之和最大值可以到 2不同论文里部分实现会对结果除以 2 做归一。对比前要确认仓库里的 SCD 函数有没有做过这一步否则数值范围直接可比会得出错误结论。SCD 中的差分方向是语义核心D1 是融合图减去源图 B它在大脑中的含义是“融合图里那些不属于 B 的成分”这些成分如果与 A 相关性越高说明 A 的独有信息融合得越好。方向一旦反了相当于拿噪声区域去和源图做相关结果往往接近 0 甚至负值翻车概率极大。3.5 Qcv 的视觉保真近似实现Qcv 在仓库中常以视觉信息保真度框架出现这里给出基于局部显著性加权的梯度相似度近似版本适合在没有原始 MATLAB 源码时快速复现。def qcv(img_a, img_b, img_f, window_size11): def _local_grad(img): gx sobel(img, axis1) gy sobel(img, axis0) return np.hypot(gx, gy) gA _local_grad(img_a) gB _local_grad(img_b) gF _local_grad(img_f) # 源图显著性均值作为视觉权重 saliency (gA gB) / 2.0 weight uniform_filter(saliency, sizewindow_size) # 融合梯度与每个源图梯度的局部相似度 sim_af 2.0 * gA * gF / (gA**2 gF**2 1e-10) sim_bf 2.0 * gB * gF / (gB**2 gF**2 1e-10) vis np.maximum(sim_af, sim_bf) return np.sum(vis * weight) / (np.sum(weight) 1e-10)窗口大小window_size控制局部显著性平滑范围11 是常见默认值。窗口越大视觉权重越趋向全局对局部细节的分辨率下降窗口太小则会引入大量零散噪声点。视觉保真族指标对窗口尺寸普遍敏感正式实验时建议固定为奇数并在论文中写明。这里的np.maximum含义是每个像素点的保真度取融合图与两个源图中视觉上更接近的那一个。如果某处结构只存在于 A 中而融合图完美保留了它sim_af 接近 1最终结果也会很好如果融合图把两边的信息都弄丢了两个相似度都会很低分数立刻掉下来。3.6 一套跑通五个指标的最小脚本def evaluate_all(img_a, img_b, img_f): a _to_float_gray(img_a) b _to_float_gray(img_b) f _to_float_gray(img_f) _check_shape(a, b, f) metrics { Qabf: qabf(a, b, f), Nabf: nabf(a, b, f), CC: cc(a, b, f), SCD: scd(a, b, f), Qcv: qcv(a, b, f), } return metrics # 用合成数据做冒烟测试 rng np.random.default_rng(42) A rng.random((128, 128)).astype(np.float64) B rng.random((128, 128)).astype(np.float64) F (A B) / 2 print(evaluate_all(A, B, F))用随机噪声做冒烟测试时能直接看出指标实现有没有犯低级错误。比如 Qabf 应该给出一个在 0.3 到 0.6 之间的值因为随机噪声图之间没有稳定边缘对应关系CC 应该接近 0.5因为 F 是两个随机图的均值整体灰度结构与各自都有中等程度相关。如果跑出来 CC 接近 1 或 Qabf 超过 0.9基本可以断定预处理或权重计算有 bug。4. 图像融合评估避坑指南5 个高频翻车现场4.1 翻车 1源图没对齐就开算指标高分却毫无意义现象同一场景的可见光与红外图像只做了粗略裁剪没有特征点配准直接输入指标库Qabf 竟然有 0.6 以上看起来“融合效果尚可”。原因Qabf、Nabf 这类梯度域指标对亚像素级偏移极其敏感但对整体平移却可能因为边缘强度分布相近而给偏高分数。CC 对平移完全不敏感甚至会给出不错的数值误导性更强。解决计算指标前先做一次特征点匹配或相位相关配准。至少要做到两幅图里同一个物理点在像素坐标上的偏差小于 1 个像素。没有对齐的数据算出来的指标只能当作算法在“未对齐场景下的退化程度”参考不能当作融合质量结论。4.2 翻车 2uint8 图没归一化Sobel 梯度全是异常值现象用 OpenCV 读入的图直接传给指标函数Qabf 输出 0.99Nabf 输出几千数值完全不可信。原因uint8 像素取值范围 0-255梯度计算结果天然偏大。归一化后边缘强度分布才符合 Sigmoid 参数的设计范围直接用原始 uint8 会把边缘信息保真度计算推到饱和区。解决在指标函数入口处强制做 float64 转换并按最大值归一化。如果图像里存在极大离群值比如热成像中的高温目标建议用百分位归一化把 99% 分位以上的值截断避免单个热源把全局最大值拉高、其他区域全部被压缩到接近 0。4.3 翻车 3边缘方向没有周期折叠Qabf 对旋转图像完全失效现象把融合图旋转 90 度后再算 Qabf分数从 0.7 跌到 0.4而肉眼看起来边缘结构几乎一样。原因直接对arctan2的结果做差的绝对值方向差的最大值可达 2π。边缘几何上等价的 0 度和 π 度被视为完全不同方向导致所有近似平行边缘都被判为方向失配。这是 Qabf 实现里最有名的隐蔽 bug。解决统一使用方向差折叠函数先把差值取模 π再把大于 π/2 的角度映射到锐角区间最后归一化到 [0,1]。写完这个函数后建议做一个自测把一张图旋转 90 度再旋转回来前后 Qabf 差异应小于 0.01。指标库抽检时这个测试能快速暴露问题。4.4 翻车 4SCD 差分方向写反互补信息被算成负相关现象同一组融合数据别人仓库算出的 SCD 是 1.2本地复现却是 -0.3且随着融合算法变化波动极大。原因SCD 的定义对差分方向极其敏感。D1 F - B 与 A 做相关D2 F - A 与 B 做相关这是标准定义。把 D1 写成 F - A语义就变成了“融合图相对 A 的差分与 A 做相关”噪声主导结果必然不稳定。解决在代码注释里显式写出每个差分图的物理含义并在冒烟测试中加入一个用例让 F A此时 SCD 中第一项应该接近 1第二项接近 0总和应该在 0.5 到 1.0 之间。跑通这个用例才能确认方向没有写反。另外需要注意部分实现会对 SCD 除以 2比较数值前先看对方公式。4.5 翻车 5Nabf 高不一定来自融合算法可能是源图自身噪声的锅现象融合算法在去噪数据上 Nabf 很低换到含噪真实数据后 Nabf 暴涨于是认为算法鲁棒性差准备换模型。原因Nabf 的权重来自源图边缘强度源图噪声越大边缘强度图越“花”加权差值自然变大。Nabf 无法区分差异来自融合算法的伪影还是源图自身携带的噪声。解决用源图 A 与源图 B 直接计算一次 Nabf把它当作基线噪声水平。融合结果的 Nabf 减去基线后才值得被解释。如果减完接近零说明融合算法至少在噪声层面没有额外引入伪影。这一招在医学影像和多模态传感器数据上特别重要因为真实数据的噪声水平往往比公开数据集高一个数量级。4.6 仓库解压后跑不通.rar 工具包的编码与依赖问题现象从网上下载的图像融合评估工具包解压后 MATLAB 脚本文件名出现乱码MEX 文件加载报错函数调用时提示找不到某个自定义工具箱。原因很多老仓库压缩时在 Windows 中文环境下使用 ANSI 编码保存文件名跨平台解压后 UTF-8 解码失败部分函数依赖 MATLAB 的图像处理工具箱或编译好的 MEX 二进制换平台就失效。解决先用 7-Zip 或 Bandizip 解压并在解压选项里开启“文件名编码自动修复”优先用 UTF-8 或 ANSI 逐个尝试。MEX 加载不了就直接放弃二进制文件用纯 Python 或 Octave 把对应指标重实现一遍。经过几次重写就会明白这类指标仓库的核心价值是公式参考而不是那几行既有代码本身。建议把论文里的公式截图和源文件放在一起存档公式永远比代码活得久。5. 用指标反推融合算法让 Qabf、SCD 等数值告诉你该改哪里指标不只是用来给别人排名的更是用来给自己找病灶的。融合算法调参时遇到一个低分别急着换网络结构先看是哪项指标在报警。Qabf 偏低且 Nabf 偏高问题往往出在融合规则对高频成分处理不当。加权平均规则最容易出现这对组合因为它在梯度域天然“和稀泥”。此时应该把融合规则改成基于显著性的选择策略或者在高频子带引入绝对值取大的操作。CC 偏低则说明整体结构已经偏离源图先检查预处理阶段是否有色彩偏移或灰度范围被截断再看融合网络是否缺少全局一致性约束。SCD 偏低说明互补信息没有单独被尊重常见于简单相加或均值融合改进方向是引入差分域损失或独立处理独有成分。Qcv 偏低但 Qabf 不低说明保真度问题出在视觉显著性区域的结构组织上多聚焦图像常见此现象处理手段是加大局部窗口匹配的权重。我自己的习惯是保留一组固定的指标校验用例一对随机噪声图、一张完全相同图、一对已知最优融合的公开样例。每次修改算法后先跑这三个用例确认指标数值变化方向符合预期再放到真实数据上做对比。这套流程帮我避免过不止一次“指标明明涨了、结果图却变差了”的尴尬场景。血泪经验告诉我指标库本身要先被验证之后它给出的每个数字才有资格指导算法迭代。希望这些经验对你把融合评估体系落地有帮助。本文还有配套的精品资源点击获取