图像融合评估指标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知识清单
文章目录 前言第一章 信息与信息资源第二章 信息社会第三章 信息交流第四章 信息技术第五章 信息组织第六章 信息管理活动第七章 信息资源人文管理第八章 信息资源经济管理第九章 信息资源系统管理第十章 信息资源管理专门化前言 参考书目:《信息管理导论(第三版)》党跃武推…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...