图像融合评估指标Python版
图像融合评估指标Python版
这篇博客利用Python把大部分图像融合指标基于图像融合评估指标复现了,从而方便大家更好的使用Python进行指标计算,以及一些I/O 操作。除了几个特征互信息的指标没有成功复现之外,其他指标均可以通过这篇博客提到的Python程序计算得到,其中SSIM和MS_SSIM是基于PyTorch实现的可能无法与原来的程序保持一致,同时使用了一些矩阵运算加速了Nabf和Qabf的计算。但不幸的是在计算VIF时设计大量的卷积运算,而博主在Python中采用cipy.signal.convolve2d来替换MATLAB中的filter函数,导致时间消耗较大,如果你不需要计算VIF可以直接注释掉相关语句 并设置VIF=1即可。
在原来的MATLAB程序中由于没有充分考虑数据类型的影响,在计算SD是会由于uint8数据类型的限制,但是部分数据被截断,在Python中已经解决了这个Bug,同时也在原来的MATLAB版本中修正了这个问题。
在Python版的程序中,只有计算EN和MI是使用的是int型数据,其他指标均使用float型数据。此外除了计算MSE和PSNR时将数据归一化到[0,1]之外,计算其他指标时,数据范围均为[0,255]。
| 评估指标 | 缩写 |
|---|---|
| 信息熵 | EN |
| 空间频率 | SF |
| 标准差 | SD |
| 峰值信噪比 | PSNR |
| 均方误差 | MSE |
| 互信息 | MI |
| 视觉保真度 | VIF |
| 平均梯度 | AG |
| 相关系数 | CC |
| 差异相关和 | SCD |
| 基于梯度的融合性能 | Qabf |
| 结构相似度测量 | SSIM |
| 多尺度结构相似度测量 | MS-SSIM |
| 基于噪声评估的融合性能 | Nabf |
性能评估指标主要分为四类,分别是基于信息论的评估指标,主要包括** EN、MI、PSNR**、基于结构相似性的评估指标,主要包括SSIM、MS_SSIM、MSE、基于图像特征的评估指标, 主要包括SF、SD、AG,基于人类视觉感知的评估指标,主要包括VIF、以及基于源图像与生成图像的评估指标,主要包括CC、SCD、Qabf、Nabf。
接下来是部分程序:
单张图像测试程序: eval_one_image.py
from PIL import Image
from Metric import *
from time import time
import warnings
warnings.filterwarnings("ignore")def evaluation_one(ir_name, vi_name, f_name):f_img = Image.open(f_name).convert('L')ir_img = Image.open(ir_name).convert('L')vi_img = Image.open(vi_name).convert('L')f_img_int = np.array(f_img).astype(np.int32)f_img_double = np.array(f_img).astype(np.float32)ir_img_int = np.array(ir_img).astype(np.int32)ir_img_double = np.array(ir_img).astype(np.float32)vi_img_int = np.array(vi_img).astype(np.int32)vi_img_double = np.array(vi_img).astype(np.float32)EN = EN_function(f_img_int)MI = MI_function(ir_img_int, vi_img_int, f_img_int, gray_level=256)SF = SF_function(f_img_double)SD = SD_function(f_img_double)AG = AG_function(f_img_double)PSNR = PSNR_function(ir_img_double, vi_img_double, f_img_double)MSE = MSE_function(ir_img_double, vi_img_double, f_img_double)VIF = VIF_function(ir_img_double, vi_img_double, f_img_double)CC = CC_function(ir_img_double, vi_img_double, f_img_double)SCD = SCD_function(ir_img_double, vi_img_double, f_img_double)Qabf = Qabf_function(ir_img_double, vi_img_double, f_img_double)Nabf = Nabf_function(ir_img_double, vi_img_double, f_img_double)SSIM = SSIM_function(ir_img_double, vi_img_double, f_img_double)MS_SSIM = MS_SSIM_function(ir_img_double, vi_img_double, f_img_double)return EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIMif __name__ == '__main__':f_name = r'E:\Desktop\metric\Test\Results\TNO\GTF\01.png'ir_name = r'E:\Desktop\metric\Test\datasets\TNO\ir\01.png'vi_name = r'E:\Desktop\metric\Test\datasets\TNO\vi\01.png'EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIM = evaluation_one(ir_name, vi_name, f_name)print('EN:', round(EN, 4))print('MI:', round(MI, 4))print('SF:', round(SF, 4))print('AG:', round(AG, 4))print('SD:', round(SD, 4))print('CC:', round(CC, 4))print('SCD:', round(SCD, 4))print('VIF:', round(VIF, 4))print('MSE:', round(MSE, 4))print('PSNR:', round(PSNR, 4))print('Qabf:', round(Qabf, 4))print('Nabf:', round(Nabf, 4))print('SSIM:', round(SSIM, 4))print('MS_SSIM:', round(MS_SSIM, 4))
测试一个方法中所有图像指标的程序: eval_one_method.py
import numpy as np
from PIL import Image
from Metric import *
from natsort import natsorted
from tqdm import tqdm
import os
import statistics
import warnings
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
warnings.filterwarnings("ignore")def write_excel(excel_name='metric.xlsx', worksheet_name='VIF', column_index=0, data=None):try:workbook = load_workbook(excel_name)except FileNotFoundError:# 文件不存在,创建新的 Workbookworkbook = Workbook()# 获取或创建一个工作表if worksheet_name in workbook.sheetnames:worksheet = workbook[worksheet_name]else:worksheet = workbook.create_sheet(title=worksheet_name)# 在指定列中插入数据column = get_column_letter(column_index + 1)for i, value in enumerate(data):cell = worksheet[column + str(i+1)]cell.value = value# 保存文件workbook.save(excel_name)def evaluation_one(ir_name, vi_name, f_name):f_img = Image.open(f_name).convert('L')ir_img = Image.open(ir_name).convert('L')vi_img = Image.open(vi_name).convert('L')f_img_int = np.array(f_img).astype(np.int32)f_img_double = np.array(f_img).astype(np.float32)ir_img_int = np.array(ir_img).astype(np.int32)ir_img_double = np.array(ir_img).astype(np.float32)vi_img_int = np.array(vi_img).astype(np.int32)vi_img_double = np.array(vi_img).astype(np.float32)EN = EN_function(f_img_int)MI = MI_function(ir_img_int, vi_img_int, f_img_int, gray_level=256)SF = SF_function(f_img_double)SD = SD_function(f_img_double)AG = AG_function(f_img_double)PSNR = PSNR_function(ir_img_double, vi_img_double, f_img_double)MSE = MSE_function(ir_img_double, vi_img_double, f_img_double)VIF = VIF_function(ir_img_double, vi_img_double, f_img_double)CC = CC_function(ir_img_double, vi_img_double, f_img_double)SCD = SCD_function(ir_img_double, vi_img_double, f_img_double)Qabf = Qabf_function(ir_img_double, vi_img_double, f_img_double)Nabf = Nabf_function(ir_img_double, vi_img_double, f_img_double)SSIM = SSIM_function(ir_img_double, vi_img_double, f_img_double)MS_SSIM = MS_SSIM_function(ir_img_double, vi_img_double, f_img_double)return EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIMif __name__ == '__main__':with_mean = TrueEN_list = []MI_list = []SF_list = []AG_list = []SD_list = []CC_list = []SCD_list = []VIF_list = []MSE_list = []PSNR_list = []Qabf_list = []Nabf_list = []SSIM_list = []MS_SSIM_list = []filename_list = ['']dataset_name = 'test_imgs'ir_dir = os.path.join('..\datasets', dataset_name, 'ir')vi_dir = os.path.join('..\datasets', dataset_name, 'vi')Method = 'SeAFusion'f_dir = os.path.join('..\Results', dataset_name, Method)save_dir = '..\Metric'os.makedirs(save_dir, exist_ok=True)metric_save_name = os.path.join(save_dir, 'metric_{}_{}.xlsx'.format(dataset_name, Method))filelist = natsorted(os.listdir(ir_dir))eval_bar = tqdm(filelist)for _, item in enumerate(eval_bar):ir_name = os.path.join(ir_dir, item)vi_name = os.path.join(vi_dir, item)f_name = os.path.join(f_dir, item)EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIM = evaluation_one(ir_name, vi_name, f_name)EN_list.append(EN)MI_list.append(MI)SF_list.append(SF)AG_list.append(AG)SD_list.append(SD)CC_list.append(CC)SCD_list.append(SCD)VIF_list.append(VIF)MSE_list.append(MSE)PSNR_list.append(PSNR)Qabf_list.append(Qabf)Nabf_list.append(Nabf)SSIM_list.append(SSIM)MS_SSIM_list.append(MS_SSIM)filename_list.append(item)eval_bar.set_description("{} | {}".format(Method, item))if with_mean:# 添加均值EN_list.append(np.mean(EN_list))MI_list.append(np.mean(MI_list))SF_list.append(np.mean(SF_list))AG_list.append(np.mean(AG_list))SD_list.append(np.mean(SD_list))CC_list.append(np.mean(CC_list))SCD_list.append(np.mean(SCD_list))VIF_list.append(np.mean(VIF_list))MSE_list.append(np.mean(MSE_list))PSNR_list.append(np.mean(PSNR_list))Qabf_list.append(np.mean(Qabf_list))Nabf_list.append(np.mean(Nabf_list))SSIM_list.append(np.mean(SSIM_list))MS_SSIM_list.append(np.mean(MS_SSIM_list))filename_list.append('mean')## 添加标准差EN_list.append(np.std(EN_list))MI_list.append(np.std(MI_list))SF_list.append(np.std(SF_list))AG_list.append(np.std(AG_list))SD_list.append(np.std(SD_list))CC_list.append(np.std(CC_list[:-1]))SCD_list.append(np.std(SCD_list))VIF_list.append(np.std(VIF_list))MSE_list.append(np.std(MSE_list))PSNR_list.append(np.std(PSNR_list))Qabf_list.append(np.std(Qabf_list))Nabf_list.append(np.std(Nabf_list))SSIM_list.append(np.std(SSIM_list))MS_SSIM_list.append(np.std(MS_SSIM_list))filename_list.append('std')## 保留三位小数EN_list = [round(x, 3) for x in EN_list]MI_list = [round(x, 3) for x in MI_list]SF_list = [round(x, 3) for x in SF_list]AG_list = [round(x, 3) for x in AG_list]SD_list = [round(x, 3) for x in SD_list]CC_list = [round(x, 3) for x in CC_list]SCD_list = [round(x, 3) for x in SCD_list]VIF_list = [round(x, 3) for x in VIF_list]MSE_list = [round(x, 3) for x in MSE_list]PSNR_list = [round(x, 3) for x in PSNR_list]Qabf_list = [round(x, 3) for x in Qabf_list]Nabf_list = [round(x, 3) for x in Nabf_list]SSIM_list = [round(x, 3) for x in SSIM_list]MS_SSIM_list = [round(x, 3) for x in MS_SSIM_list]EN_list.insert(0, '{}'.format(Method))MI_list.insert(0, '{}'.format(Method))SF_list.insert(0, '{}'.format(Method))AG_list.insert(0, '{}'.format(Method))SD_list.insert(0, '{}'.format(Method))CC_list.insert(0, '{}'.format(Method))SCD_list.insert(0, '{}'.format(Method))VIF_list.insert(0, '{}'.format(Method))MSE_list.insert(0, '{}'.format(Method))PSNR_list.insert(0, '{}'.format(Method))Qabf_list.insert(0, '{}'.format(Method))Nabf_list.insert(0, '{}'.format(Method))SSIM_list.insert(0, '{}'.format(Method))MS_SSIM_list.insert(0, '{}'.format(Method))write_excel(metric_save_name, 'EN', 0, filename_list)write_excel(metric_save_name, "MI", 0, filename_list)write_excel(metric_save_name, "SF", 0, filename_list)write_excel(metric_save_name, "AG", 0, filename_list)write_excel(metric_save_name, "SD", 0, filename_list)write_excel(metric_save_name, "CC", 0, filename_list)write_excel(metric_save_name, "SCD", 0, filename_list)write_excel(metric_save_name, "VIF", 0, filename_list)write_excel(metric_save_name, "MSE", 0, filename_list)write_excel(metric_save_name, "PSNR", 0, filename_list)write_excel(metric_save_name, "Qabf", 0, filename_list)write_excel(metric_save_name, "Nabf", 0, filename_list)write_excel(metric_save_name, "SSIM", 0, filename_list)write_excel(metric_save_name, "MS_SSIM", 0, filename_list)write_excel(metric_save_name, 'EN', 1, EN_list)write_excel(metric_save_name, 'MI', 1, MI_list)write_excel(metric_save_name, 'SF', 1, SF_list)write_excel(metric_save_name, 'AG', 1, AG_list)write_excel(metric_save_name, 'SD', 1, SD_list)write_excel(metric_save_name, 'CC', 1, CC_list)write_excel(metric_save_name, 'SCD', 1, SCD_list)write_excel(metric_save_name, 'VIF', 1, VIF_list)write_excel(metric_save_name, 'MSE', 1, MSE_list)write_excel(metric_save_name, 'PSNR', 1, PSNR_list)write_excel(metric_save_name, 'Qabf', 1, Qabf_list)write_excel(metric_save_name, 'Nabf', 1, Nabf_list)write_excel(metric_save_name, 'SSIM', 1, SSIM_list)write_excel(metric_save_name, 'MS_SSIM', 1, MS_SSIM_list)
测试一个数据集上所有对比算法的指标的程序:eval_multi_method.py
import numpy as np
from PIL import Image
from Metric import *
from natsort import natsorted
from tqdm import tqdm
import os
import statistics
import warnings
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
warnings.filterwarnings("ignore")def write_excel(excel_name='metric.xlsx', worksheet_name='VIF', column_index=0, data=None):try:workbook = load_workbook(excel_name)except FileNotFoundError:# 文件不存在,创建新的 Workbookworkbook = Workbook()# 获取或创建一个工作表if worksheet_name in workbook.sheetnames:worksheet = workbook[worksheet_name]else:worksheet = workbook.create_sheet(title=worksheet_name)# 在指定列中插入数据column = get_column_letter(column_index + 1)for i, value in enumerate(data):cell = worksheet[column + str(i+1)]cell.value = value# 保存文件workbook.save(excel_name)def evaluation_one(ir_name, vi_name, f_name):f_img = Image.open(f_name).convert('L')ir_img = Image.open(ir_name).convert('L')vi_img = Image.open(vi_name).convert('L')f_img_int = np.array(f_img).astype(np.int32)f_img_double = np.array(f_img).astype(np.float32)ir_img_int = np.array(ir_img).astype(np.int32)ir_img_double = np.array(ir_img).astype(np.float32)vi_img_int = np.array(vi_img).astype(np.int32)vi_img_double = np.array(vi_img).astype(np.float32)EN = EN_function(f_img_int)MI = MI_function(ir_img_int, vi_img_int, f_img_int, gray_level=256)SF = SF_function(f_img_double)SD = SD_function(f_img_double)AG = AG_function(f_img_double)PSNR = PSNR_function(ir_img_double, vi_img_double, f_img_double)MSE = MSE_function(ir_img_double, vi_img_double, f_img_double)VIF = VIF_function(ir_img_double, vi_img_double, f_img_double)CC = CC_function(ir_img_double, vi_img_double, f_img_double)SCD = SCD_function(ir_img_double, vi_img_double, f_img_double)Qabf = Qabf_function(ir_img_double, vi_img_double, f_img_double)Nabf = Nabf_function(ir_img_double, vi_img_double, f_img_double)SSIM = SSIM_function(ir_img_double, vi_img_double, f_img_double)MS_SSIM = MS_SSIM_function(ir_img_double, vi_img_double, f_img_double)return EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIMif __name__ == '__main__':with_mean = Truedataroot = r'../datasets'results_root = '../Results'dataset = 'TNO'ir_dir = os.path.join(dataroot, dataset, 'ir')vi_dir = os.path.join(dataroot, dataset, 'vi')f_dir = os.path.join(results_root, dataset)save_dir = '../Metric'os.makedirs(save_dir, exist_ok=True)metric_save_name = os.path.join(save_dir, 'metric_{}.xlsx'.format(dataset))filelist = natsorted(os.listdir(ir_dir))Method_list = ['GTF', 'DIDFuse', 'RFN-Nest', 'FusionGAN', 'TarDAL', 'UMF-CMGR', 'SeAFusion', 'SwinFusion', 'U2Fusion', 'PSF']for i, Method in enumerate(Method_list):EN_list = []MI_list = []SF_list = []AG_list = []SD_list = []CC_list = []SCD_list = []VIF_list = []MSE_list = []PSNR_list = []Qabf_list = []Nabf_list = []SSIM_list = []MS_SSIM_list = []filename_list = ['']sub_f_dir = os.path.join(f_dir, Method)eval_bar = tqdm(filelist)for _, item in enumerate(eval_bar):ir_name = os.path.join(ir_dir, item)vi_name = os.path.join(vi_dir, item)f_name = os.path.join(sub_f_dir, item)print(ir_name, vi_name, f_name)EN, MI, SF, AG, SD, CC, SCD, VIF, MSE, PSNR, Qabf, Nabf, SSIM, MS_SSIM = evaluation_one(ir_name, vi_name, f_name)EN_list.append(EN)MI_list.append(MI)SF_list.append(SF)AG_list.append(AG)SD_list.append(SD)CC_list.append(CC)SCD_list.append(SCD)VIF_list.append(VIF)MSE_list.append(MSE)PSNR_list.append(PSNR)Qabf_list.append(Qabf)Nabf_list.append(Nabf)SSIM_list.append(SSIM)MS_SSIM_list.append(MS_SSIM)filename_list.append(item)eval_bar.set_description("{} | {}".format(Method, item))if with_mean:# 添加均值EN_list.append(np.mean(EN_list))MI_list.append(np.mean(MI_list))SF_list.append(np.mean(SF_list))AG_list.append(np.mean(AG_list))SD_list.append(np.mean(SD_list))CC_list.append(np.mean(CC_list))SCD_list.append(np.mean(SCD_list))VIF_list.append(np.mean(VIF_list))MSE_list.append(np.mean(MSE_list))PSNR_list.append(np.mean(PSNR_list))Qabf_list.append(np.mean(Qabf_list))Nabf_list.append(np.mean(Nabf_list))SSIM_list.append(np.mean(SSIM_list))MS_SSIM_list.append(np.mean(MS_SSIM_list))filename_list.append('mean')## 添加标准差EN_list.append(np.std(EN_list))MI_list.append(np.std(MI_list))SF_list.append(np.std(SF_list))AG_list.append(np.std(AG_list))SD_list.append(np.std(SD_list))CC_list.append(np.std(CC_list[:-1]))SCD_list.append(np.std(SCD_list))VIF_list.append(np.std(VIF_list))MSE_list.append(np.std(MSE_list))PSNR_list.append(np.std(PSNR_list))Qabf_list.append(np.std(Qabf_list))Nabf_list.append(np.std(Nabf_list))SSIM_list.append(np.std(SSIM_list))MS_SSIM_list.append(np.std(MS_SSIM_list))filename_list.append('std')## 保留三位小数EN_list = [round(x, 3) for x in EN_list]MI_list = [round(x, 3) for x in MI_list]SF_list = [round(x, 3) for x in SF_list]AG_list = [round(x, 3) for x in AG_list]SD_list = [round(x, 3) for x in SD_list]CC_list = [round(x, 3) for x in CC_list]SCD_list = [round(x, 3) for x in SCD_list]VIF_list = [round(x, 3) for x in VIF_list]MSE_list = [round(x, 3) for x in MSE_list]PSNR_list = [round(x, 3) for x in PSNR_list]Qabf_list = [round(x, 3) for x in Qabf_list]Nabf_list = [round(x, 3) for x in Nabf_list]SSIM_list = [round(x, 3) for x in SSIM_list]MS_SSIM_list = [round(x, 3) for x in MS_SSIM_list]EN_list.insert(0, '{}'.format(Method))MI_list.insert(0, '{}'.format(Method))SF_list.insert(0, '{}'.format(Method))AG_list.insert(0, '{}'.format(Method))SD_list.insert(0, '{}'.format(Method))CC_list.insert(0, '{}'.format(Method))SCD_list.insert(0, '{}'.format(Method))VIF_list.insert(0, '{}'.format(Method))MSE_list.insert(0, '{}'.format(Method))PSNR_list.insert(0, '{}'.format(Method))Qabf_list.insert(0, '{}'.format(Method))Nabf_list.insert(0, '{}'.format(Method))SSIM_list.insert(0, '{}'.format(Method))MS_SSIM_list.insert(0, '{}'.format(Method))if i == 0:write_excel(metric_save_name, 'EN', 0, filename_list)write_excel(metric_save_name, "MI", 0, filename_list)write_excel(metric_save_name, "SF", 0, filename_list)write_excel(metric_save_name, "AG", 0, filename_list)write_excel(metric_save_name, "SD", 0, filename_list)write_excel(metric_save_name, "CC", 0, filename_list)write_excel(metric_save_name, "SCD", 0, filename_list)write_excel(metric_save_name, "VIF", 0, filename_list)write_excel(metric_save_name, "MSE", 0, filename_list)write_excel(metric_save_name, "PSNR", 0, filename_list)write_excel(metric_save_name, "Qabf", 0, filename_list)write_excel(metric_save_name, "Nabf", 0, filename_list)write_excel(metric_save_name, "SSIM", 0, filename_list)write_excel(metric_save_name, "MS_SSIM", 0, filename_list)write_excel(metric_save_name, 'EN', i + 1, EN_list)write_excel(metric_save_name, 'MI', i + 1, MI_list)write_excel(metric_save_name, 'SF', i + 1, SF_list)write_excel(metric_save_name, 'AG', i + 1, AG_list)write_excel(metric_save_name, 'SD', i + 1, SD_list)write_excel(metric_save_name, 'CC', i + 1, CC_list)write_excel(metric_save_name, 'SCD', i + 1, SCD_list)write_excel(metric_save_name, 'VIF', i + 1, VIF_list)write_excel(metric_save_name, 'MSE', i + 1, MSE_list)write_excel(metric_save_name, 'PSNR', i + 1, PSNR_list)write_excel(metric_save_name, 'Qabf', i + 1, Qabf_list)write_excel(metric_save_name, 'Nabf', i + 1, Nabf_list)write_excel(metric_save_name, 'SSIM', i + 1, SSIM_list)write_excel(metric_save_name, 'MS_SSIM', i + 1, MS_SSIM_list)
在上述三个程序中均需调用 Metric.py函数:
import numpy as np
from scipy.signal import convolve2d
from Qabf import get_Qabf
from Nabf import get_Nabf
import math
from ssim import ssim, ms_ssimdef EN_function(image_array):# 计算图像的直方图histogram, bins = np.histogram(image_array, bins=256, range=(0, 255))# 将直方图归一化histogram = histogram / float(np.sum(histogram))# 计算熵entropy = -np.sum(histogram * np.log2(histogram + 1e-7))return entropydef SF_function(image):image_array = np.array(image)RF = np.diff(image_array, axis=0)RF1 = np.sqrt(np.mean(np.mean(RF ** 2)))CF = np.diff(image_array, axis=1)CF1 = np.sqrt(np.mean(np.mean(CF ** 2)))SF = np.sqrt(RF1 ** 2 + CF1 ** 2)return SFdef SD_function(image_array):m, n = image_array.shapeu = np.mean(image_array)SD = np.sqrt(np.sum(np.sum((image_array - u) ** 2)) / (m * n))return SDdef PSNR_function(A, B, F):A = A / 255.0B = B / 255.0F = F / 255.0m, n = F.shapeMSE_AF = np.sum(np.sum((F - A)**2))/(m*n)MSE_BF = np.sum(np.sum((F - B)**2))/(m*n)MSE = 0.5 * MSE_AF + 0.5 * MSE_BFPSNR = 20 * np.log10(255/np.sqrt(MSE))return PSNRdef MSE_function(A, B, F):A = A / 255.0B = B / 255.0F = F / 255.0m, n = F.shapeMSE_AF = np.sum(np.sum((F - A)**2))/(m*n)MSE_BF = np.sum(np.sum((F - B)**2))/(m*n)MSE = 0.5 * MSE_AF + 0.5 * MSE_BFreturn MSEdef fspecial_gaussian(shape, sigma):"""2D gaussian mask - should give the same result as MATLAB's fspecial('gaussian',...)"""m, n = [(ss-1.)/2. for ss in shape]y, x = np.ogrid[-m:m+1, -n:n+1]h = np.exp(-(x*x + y*y) / (2.*sigma*sigma))h[h < np.finfo(h.dtype).eps*h.max()] = 0sumh = h.sum()if sumh != 0:h /= sumhreturn hdef vifp_mscale(ref, dist):sigma_nsq = 2num = 0den = 0for scale in range(1, 5):N = 2**(4-scale+1)+1win = fspecial_gaussian((N, N), N/5)if scale > 1:ref = convolve2d(ref, win, mode='valid')dist = convolve2d(dist, win, mode='valid')ref = ref[::2, ::2]dist = dist[::2, ::2]mu1 = convolve2d(ref, win, mode='valid')mu2 = convolve2d(dist, win, mode='valid')mu1_sq = mu1*mu1mu2_sq = mu2*mu2mu1_mu2 = mu1*mu2sigma1_sq = convolve2d(ref*ref, win, mode='valid') - mu1_sqsigma2_sq = convolve2d(dist*dist, win, mode='valid') - mu2_sqsigma12 = convolve2d(ref*dist, win, mode='valid') - mu1_mu2sigma1_sq[sigma1_sq<0] = 0sigma2_sq[sigma2_sq<0] = 0g = sigma12 / (sigma1_sq + 1e-10)sv_sq = sigma2_sq - g*sigma12g[sigma1_sq<1e-10] = 0sv_sq[sigma1_sq<1e-10] = sigma2_sq[sigma1_sq<1e-10]sigma1_sq[sigma1_sq<1e-10] = 0g[sigma2_sq<1e-10] = 0sv_sq[sigma2_sq<1e-10] = 0sv_sq[g<0] = sigma2_sq[g<0]g[g<0] = 0sv_sq[sv_sq<=1e-10] = 1e-10num += np.sum(np.log10(1+g**2 * sigma1_sq/(sv_sq+sigma_nsq)))den += np.sum(np.log10(1+sigma1_sq/sigma_nsq))vifp = num/denreturn vifpdef VIF_function(A, B, F):VIF = vifp_mscale(A, F) + vifp_mscale(B, F)return VIFdef CC_function(A,B,F):rAF = np.sum((A - np.mean(A)) * (F - np.mean(F))) / np.sqrt(np.sum((A - np.mean(A)) ** 2) * np.sum((F - np.mean(F)) ** 2))rBF = np.sum((B - np.mean(B)) * (F - np.mean(F))) / np.sqrt(np.sum((B - np.mean(B)) ** 2) * np.sum((F - np.mean(F)) ** 2))CC = np.mean([rAF, rBF])return CCdef corr2(a, b):a = a - np.mean(a)b = b - np.mean(b)r = np.sum(a * b) / np.sqrt(np.sum(a * a) * np.sum(b * b))return rdef SCD_function(A, B, F):r = corr2(F - B, A) + corr2(F - A, B)return rdef Qabf_function(A, B, F):return get_Qabf(A, B, F)def Nabf_function(A, B, F):return Nabf_function(A, B, F)def Hab(im1, im2, gray_level):hang, lie = im1.shapecount = hang * lieN = gray_levelh = np.zeros((N, N))for i in range(hang):for j in range(lie):h[im1[i, j], im2[i, j]] = h[im1[i, j], im2[i, j]] + 1h = h / np.sum(h)im1_marg = np.sum(h, axis=0)im2_marg = np.sum(h, axis=1)H_x = 0H_y = 0for i in range(N):if (im1_marg[i] != 0):H_x = H_x + im1_marg[i] * math.log2(im1_marg[i])for i in range(N):if (im2_marg[i] != 0):H_x = H_x + im2_marg[i] * math.log2(im2_marg[i])H_xy = 0for i in range(N):for j in range(N):if (h[i, j] != 0):H_xy = H_xy + h[i, j] * math.log2(h[i, j])MI = H_xy - H_x - H_yreturn MIdef MI_function(A, B, F, gray_level=256):MIA = Hab(A, F, gray_level)MIB = Hab(B, F, gray_level)MI_results = MIA + MIBreturn MI_resultsdef AG_function(image):width = image.shape[1]width = width - 1height = image.shape[0]height = height - 1tmp = 0.0[grady, gradx] = np.gradient(image)s = np.sqrt((np.square(gradx) + np.square(grady)) / 2)AG = np.sum(np.sum(s)) / (width * height)return AGdef SSIM_function(A, B, F):ssim_A = ssim(A, F)ssim_B = ssim(B, F)SSIM = 1 * ssim_A + 1 * ssim_Breturn SSIM.item()def MS_SSIM_function(A, B, F):ssim_A = ms_ssim(A, F)ssim_B = ms_ssim(B, F)MS_SSIM = 1 * ssim_A + 1 * ssim_Breturn MS_SSIM.item()def Nabf_function(A, B, F):Nabf = get_Nabf(A, B, F)return Nabf
完整demo下载地址:https://download.csdn.net/download/fovever_/87530213
指标复现不易,如果您使用了我们的程序请点赞,收藏,关注三连哦。
如果您觉得我们的程序对您的科研有用,请移步Github:https://github.com/Linfeng-Tang 引用博主的相关文献,整理不易,您的支持是我们持续开源相关程序的动力。
如有疑问可添加博主QQ:2458707789@qq.com 请备注:( 学校+姓名 ),否则不予通过好友申请。
相关文章:
图像融合评估指标Python版
图像融合评估指标Python版 这篇博客利用Python把大部分图像融合指标基于图像融合评估指标复现了,从而方便大家更好的使用Python进行指标计算,以及一些I/O 操作。除了几个特征互信息的指标没有成功复现之外,其他指标均可以通过这篇博客提到的P…...
20230303----重返学习-函数概念-函数组成-函数调用-形参及匿名函数及自调用函数
day-019-nineteen-20230303-函数概念-函数组成-函数调用-形参及匿名函数及自调用函数 变量 变量声明 变量 声明定义(赋值) var num;num 100; 声明与赋值分开var num 100; 声明时就赋值 赋值只能声明一次,可以赋值无数次 变量声明关键词 varconstletclassfunctio…...
Java面试题总结
文章目录前言1、JDK1.8 的新特性有哪些?2、JDK 和 JRE 有什么区别?3、String,StringBuilder,StringBuffer 三者的区别?4、为什么 String 拼接的效率低?5、ArrayList 和 LinkedList 有哪些区别?6…...
深圳大学计软《面向对象的程序设计》实验7 拷贝构造函数与复合类
A. Point&Circle(复合类与构造) 题目描述 类Point是我们写过的一个类,类Circle是一个新的类,Point作为其成员对象,请完成类Circle的成员函数的实现。 在主函数中生成一个圆和若干个点,判断这些点与圆的位置关系,…...
Java的JVM(Java虚拟机)参数配置
JVM原理 (1)jvm是java的核心和基础,在java编译器和os平台之间的虚拟处理器,可在上面执行字节码程序。 (2)java编译器只要面向jvm,生成jvm能理解的字节码文件。java源文件经编译成字节码程序&a…...
leetcode 困难 —— 数据流的中位数(优先队列)
题目: 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化…...
7个常用的原生JS数组方法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 7个常用的原生JS数组方法一、Array.map()二、Array.filter三、Array.reduce四、Array.forEach五、Array.find六、Array.every七、Array.some总结一、Array.map() 作用&#…...
一、一篇文章打好高数基础-函数
1.连续函数的性质考点分析函数的连续性主要考察函数的奇偶性、有界性、单调性、周期性。例题判断函数的奇偶性的有界区间为() A.(-1,0) B(0,1) C(1,2) D(2,3)2.闭区间上连续函数的性质考点分析闭区间上连续函数的性质主要考察函数的最大最小值定理、零点…...
pipenv的基本使用
一. pipenv 基础 pipenv安装: pip install pipenvpipenv常用命令 pipenv --python 3 # 创建python3虚拟环境 pipenv --venv # 查看创建的虚拟环境 pipenv install 包名 # 安装包 pipenv shell # 切换到虚拟环境中 pip list # 查看当前已经安装的包࿰…...
OpenCV入门(三)快速学会OpenCV2图像处理基础
OpenCV入门(三)快速学会OpenCV2图像处理基础 1.颜色变换cvtColor imgproc的模块名称是由image(图像)和process(处理)两个单词的缩写组合而成的,是重要的图像处理模块,主要包括图像…...
基于PySide6的MySql数据库快照备份与恢复软件
db-camera 软件介绍 db-camera是一款MySql数据库备份(快照保存)与恢复软件。功能上与dump类似,但是提供了相对有好的交互界面,能够有效地管理导出的sql文件。 使用场景 开发阶段、测试阶段,尤其适合单人开发的小项目…...
BI不是报表,千万不要混淆
商业智能BI作为商业世界的新宠儿,在市场上实现了高速增长并获得了各领域企业的口碑赞誉。 很多企业把商业智能BI做成了纯报表,二维表格的数据展现形式,也有一些简单的图表可视化。但是这些简单的商业智能BI可视化报表基本上只服务到了一线的…...
sizeof以及strlen的用法以及注意事项
大家都知道,在c中算字符串长度和所占空间大小事不可避免的,甚至再有的时候,我们在写代码的过程中,就会用到这些数据。比如,下面这道题 struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4];…...
数据结构-链表-单链表(3)
目录 1. 顺序表的缺陷 2. 单链表 2.1 单链表的基本结构与接口函数 2.2 重要接口 创建新节点的函数: 2.2.1 尾插 2.2.2 头插 2.2.3 尾删 2.2.4 头删 2.2.5 查找 2.2.6 插入 2.2.7 删除 2.2.8 从pos后面插入 2.2.9 从pos后面删除 3. 链表的缺陷与优势&…...
【SpringBoot初级篇】JdbcTemplate常用方法
【SpringBoot初级篇】JdbcTemplate常用方法JdbcTemplate 查询JdbcTemplate 插入、更新、删除execute执行任意的SQLNamedParameterJdbcTemplate函数场景说明update(String sql, Nullable Object… args)增,删,改queryForObject(sql, Integer.class)查询返…...
React(三):脚手架、组件化、生命周期、父子组件通信、插槽、Context
React(三)一、脚手架安装和创建1.安装脚手架2.创建脚手架3.看看脚手架目录4.运行脚手架二、脚手架下从0开始写代码三、组件化1.类组件2.函数组件四、React的生命周期1.认识生命周期2.图解生命周期(1)Constructor(2&…...
[教程]使用 Git 克隆指定分支
Git 是我们开发过程中经常使用到的版本管理工具,在平常情况下我们从远程克隆的时候会将整个库克隆下来,这会包括整个版本库的历史提交记录和远程库里的所有分支。但在一些情况下,比如我们并不需要查看历史提交记录而只是希望能够获取到最新的代码&#x…...
Redis实现服务注册与服务发现源码阅读(Go语言)
Redis实现服务注册与服务发现源码阅读 背景 近期在看开源项目CloudWeGo中看到目前GoLang微服务框架Hertz中支持通过Redis实现服务注册与服务发现功能。便想着阅读下源码 源码阅读 gut clone了hertz-contrib后看到在一级目录下有目前各种主流的服务注册与发现的实现方案。为…...
论文复现-3
模型构建中的运算 数据集是CONLL03 这个数据集共有4种实体类型,所以,在做实体描述的embedding时,得到的语义表示的Tensor大小为 : 4*max_len, 具体指的是: type_input_ids: torch.LongTensor None, type_attention_m…...
667知识点 | 经过三年实战检验的667知识清单
文章目录 前言第一章 信息与信息资源第二章 信息社会第三章 信息交流第四章 信息技术第五章 信息组织第六章 信息管理活动第七章 信息资源人文管理第八章 信息资源经济管理第九章 信息资源系统管理第十章 信息资源管理专门化前言 参考书目:《信息管理导论(第三版)》党跃武推…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
