关于图像融合论文中的常用技术指标(附加代码)

大家好,我是reedsways,最近大概做了三篇paper的工作,都和图像融合有关,因此,特意搞一个帖子来记录一下,那些常用的图像融合的量化指标!

首先,就是PSNR和SSIM的技术指标:

首先介绍一下:

直接上自用代码:

from tqdm import tqdm
import torch
import os
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import numpy as np
import cv2
from skimage.metrics import peak_signal_noise_ratio as psnr_loss
from skimage.metrics import structural_similarity as ssim_loss
import argparse



#直接在这里修改!!!!!!!!!!!
parser = argparse.ArgumentParser(description='PSNR SSIM script', add_help=False)
parser.add_argument('--input_images_path', default='./图片名字')
parser.add_argument('--image2smiles2image_save_path', default='./另一个图片的名字')

args = parser.parse_args()


def is_png_file(filename):
    return any(filename.endswith(extension) for extension in [".jpg", ".png", ".bmp"])


def load_img(filepath):
    img = cv2.cvtColor(cv2.imread(filepath), cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32)
    img = img / 255.
    return img


class DataLoaderVal(Dataset):
    def __init__(self, target_transform=None):
        super(DataLoaderVal, self).__init__()

        self.target_transform = target_transform

        gt_dir = args.input_images_path
        input_dir = args.image2smiles2image_save_path

        clean_files = sorted(os.listdir(os.path.join(gt_dir)))
        noisy_files = sorted(os.listdir(os.path.join(input_dir)))

        self.clean_filenames = [os.path.join(gt_dir, x) for x in clean_files if is_png_file(x)]
        self.noisy_filenames = [os.path.join(input_dir, x) for x in noisy_files if is_png_file(x)]

        self.tar_size = len(self.clean_filenames)

    def __len__(self):
        return self.tar_size

    def __getitem__(self, index):
        tar_index = index % self.tar_size

        clean = torch.from_numpy(np.float32(load_img(self.clean_filenames[tar_index])))
        noisy = torch.from_numpy(np.float32(load_img(self.noisy_filenames[tar_index])))

        clean_filename = os.path.split(self.clean_filenames[tar_index])[-1]
        noisy_filename = os.path.split(self.noisy_filenames[tar_index])[-1]

        clean = clean.permute(2, 0, 1)
        noisy = noisy.permute(2, 0, 1)

        return clean, noisy, clean_filename, noisy_filename


def get_validation_data():
    return DataLoaderVal(None)


test_dataset = get_validation_data()
test_loader = DataLoader(dataset=test_dataset, batch_size=1, shuffle=False, num_workers=0, drop_last=False)

if __name__ == '__main__':

    psnr_val_rgb = []
    ssim_val_rgb = []
    for ii, data_test in enumerate(tqdm(test_loader), 0):
        rgb_groundtruth = data_test[0].numpy().squeeze().transpose((1, 2, 0))
        rgb_restored = data_test[1].cuda()

        rgb_restored = torch.clamp(rgb_restored, 0, 1).cpu().numpy().squeeze().transpose((1, 2, 0))
        psnr_val_rgb.append(psnr_loss(rgb_restored, rgb_groundtruth))
        ssim_val_rgb.append(ssim_loss(rgb_restored, rgb_groundtruth, multichannel=True))

    psnr_val_rgb = sum(psnr_val_rgb) / len(test_dataset)
    ssim_val_rgb = sum(ssim_val_rgb) / len(test_dataset)
    print("PSNR: %f, SSIM: %f " % (psnr_val_rgb, ssim_val_rgb))

接下来就是一些非参考的评价指标!!包括了! Brenner、Laplacian、SMD、SMD2、Variance、Energy、Vollath and Entropy!

直接上代码(都是值越大越好):

import cv2
import numpy as np
import math


# brenner梯度函数计算
def brenner(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    shape = np.shape(img)
    out = 0
    for x in range(0, shape[0] - 2):
        for y in range(0, shape[1]):
            out += (int(img[x + 2, y]) - int(img[x, y])) ** 2
    return out


# Laplacian梯度函数计算
def Laplacian(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    return cv2.Laplacian(img, cv2.CV_64F).var()


# SMD梯度函数计算
def SMD(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    shape = np.shape(img)
    out = 0
    for x in range(1, shape[0] - 1):
        for y in range(0, shape[1]):
            out += math.fabs(int(img[x, y]) - int(img[x, y - 1]))
            out += math.fabs(int(img[x, y] - int(img[x + 1, y])))
    return out


# SMD2梯度函数计算
def SMD2(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    shape = np.shape(img)
    out = 0
    for x in range(0, shape[0] - 1):
        for y in range(0, shape[1] - 1):
            out += math.fabs(int(img[x, y]) - int(img[x + 1, y])) * math.fabs(int(img[x, y] - int(img[x, y + 1])))
    return out


# 方差函数计算
def variance(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    out = 0
    u = np.mean(img)
    shape = np.shape(img)
    for x in range(0, shape[0]):
        for y in range(0, shape[1]):
            out += (img[x, y] - u) ** 2
    return out


# energy函数计算
def energy(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    shape = np.shape(img)
    out = 0
    for x in range(0, shape[0] - 1):
        for y in range(0, shape[1] - 1):
            out += ((int(img[x + 1, y]) - int(img[x, y])) ** 2) * ((int(img[x, y + 1] - int(img[x, y]))) ** 2)
    return out


# Vollath函数计算
def Vollath(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    shape = np.shape(img)
    u = np.mean(img)
    out = -shape[0] * shape[1] * (u ** 2)
    for x in range(0, shape[0] - 1):
        for y in range(0, shape[1]):
            out += int(img[x, y]) * int(img[x + 1, y])
    return out


# entropy函数计算
def entropy(img):
    '''
    :param img:narray 二维灰度图像
    :return: float 图像越清晰越大
    '''
    out = 0
    count = np.shape(img)[0] * np.shape(img)[1]
    p = np.bincount(np.array(img).flatten())
    for i in range(0, len(p)):
        if p[i] != 0:
            out -= p[i] * math.log(p[i] / count) / count
    return out


def main(img1):
    print('Brenner', brenner(img1) * 1e-6 )
    print('Laplacian', Laplacian(img1) * 1e-2 )
    print('SMD', SMD(img1) * 1e-5 )
    print('SMD2', SMD2(img1) * 1e-5 )
    print('Variance', variance(img1) * 1e-7 )
    print('Energy', energy(img1) * 1e-8 )
    print('Vollath', Vollath(img1) * 1e-7 )
    print('Entropy', entropy(img1))


if __name__ == '__main__':
    # 读入原始图像
    img1 = cv2.imread('input_images/name.jpg')
    # 灰度化处理
    img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    main(img1)

最后最后,超级常用的四个参数!

信息熵!

import cv2
import numpy as np
import math

tmp = []
for i in range(256):
    tmp.append(0)
val = 0
k = 0
res = 0
# 'img/1-3.jpg'=6.0404 ;  out2.jpg=7.0361 ;result2=7.1585
image = cv2.imread('input_images/name.jpg', 0)
img = np.array(image)
for i in range(len(img)):
    for j in range(len(img[i])):
        val = img[i][j]
        tmp[val] = float(tmp[val] + 1)
        k = float(k + 1)
for i in range(len(tmp)):
    tmp[i] = float(tmp[i] / k)
for i in range(len(tmp)):
    if (tmp[i] == 0):
        res = res
    else:
        res = float(res - tmp[i] * (math.log(tmp[i]) / math.log(2.0)))
print(res)

均值和标准差!

from PIL import Image, ImageStat
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('input_images/name.jpg')
img = img.astype(np.float32) / 255
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# plt.imshow(img)

cv2.imshow('img', img)
# 通过img.copy()方法,复制img的数据到mean_img
mean_img = img.copy()
# 使用 .mean() 方法可得出 mean_img 的平均值
print(mean_img.mean())
# mean_img -= mean_img.mean() 等效于 mean_img = mean_img - mean_img.mean()
# 减去平均值,得出零平均值矩阵
mean_img -= mean_img.mean()
# 显示图像
# cv2.imshow(mean_img)
cv2.imshow('mean_img', mean_img)

std_img = mean_img.copy()
# 输出 std_img 的标准差
print(std_img.std())

# std_img /= std_img.mean() 等效于 std_img = std_img / std_img.mean()
# 除于标准差,得出单位方差矩阵
std_img /= std_img.std()
# 显示图像
# plt.imshow(std_img)
cv2.imshow('std_img', std_img)

cv2.waitKey(0)
cv2.destroyAllWindows()

平均梯度!

import cv2 as cv

import numpy as np

'''图像梯度(由x,y方向上的偏导数和偏移构成),有一阶导数(sobel算子)和二阶导数(Laplace算子)
用于求解图像边缘,一阶的极大值,二阶的零点
一阶偏导在图像中为一阶差分,再变成算子(即权值)与图像像素值乘积相加,二阶同理
'''


def sobel_demo(image):
    grad_x = cv.Sobel(image, cv.CV_32F, 1, 0)  # 采用Scharr边缘更突出

    grad_y = cv.Sobel(image, cv.CV_32F, 0, 1)

    gradx = cv.convertScaleAbs(grad_x)  # 由于算完的图像有正有负,所以对其取绝对值

    grady = cv.convertScaleAbs(grad_y)

    # 计算两个图像的权值和,dst = src1alpha + src2beta + gamma

    gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)

    cv.imshow("gradx", gradx)

    cv.imshow("grady", grady)

    cv.imshow("gradient", gradxy)


def laplace_demo(image):  # 二阶导数,边缘更细
    dst = cv.Laplacian(image, cv.CV_32F)

    lpls = cv.convertScaleAbs(dst)

    cv.imshow("laplace_demo", lpls)


def custom_laplace(image):
    # 以下算子与上面的Laplace_demo()是一样的,增强采用np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])

    dst = cv.filter2D(image, cv.CV_32F, kernel=kernel)

    lpls = cv.convertScaleAbs(dst)

    cv.imshow("custom_laplace", lpls)


def Scharr(img):
    scharrx = cv.Scharr(img, cv.CV_64F, dx=1, dy=0)
    scharrx = cv.convertScaleAbs(scharrx)

    scharry = cv.Scharr(img, cv.CV_64F, dx=0, dy=1)
    scharry = cv.convertScaleAbs(scharry)

    result = cv.addWeighted(scharrx, 0.5, scharry, 0.5, 0)

    cv.imshow("scharrx", scharrx)
    cv.imshow("scharry", scharry)
    cv.imshow("result", result)


src = cv.imread("input_images/name.jpg")

cv.imshow("original", src)

sobel_demo(src)

laplace_demo(src)

# custom_laplace(src)
Scharr(src)

cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口

cv.destroyAllWindows()  # 关闭所有窗口

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
图像融合的评价指标可以从以下几个方面考虑: 1. 像素级别的相似度:衡量生成图像和目标图像在像素级别上的相似度,可以使用均方误差(Mean Squared Error, MSE)或峰值信噪比(Peak Signal to Noise Ratio, PSNR)等指标。其,MSE表示生成图像和目标图像像素值的平方差的平均值,PSNR表示生成图像和目标图像之间的信噪比,它是MSE的一种衍生量。 2. 结构相似性:衡量生成图像和目标图像在结构上的相似度,可以使用结构相似性指数(Structural Similarity Index, SSIM)等指标。SSIM指标可以同时考虑图像的亮度、对比度和结构信息,它能够更好地衡量图像之间的结构相似性。 3. 语义级别的相似度:衡量生成图像和目标图像在语义级别上的相似度,可以使用语义分割指标(例如IoU)或语义分割网络等指标。语义分割指标可以量化生成图像和目标图像在语义上的相似度,语义分割网络可以通过训练生成图像和目标图像的语义分割结果来衡量它们在语义上的相似度。 以下是一个示例代码,包含了几个常用的评价指标: ```python import torch import torch.nn.functional as F from skimage.metrics import structural_similarity as ssim from skimage.metrics import peak_signal_noise_ratio as psnr # 定义生成图像和目标图像 generated_image = ... target_image = ... # 计算像素级别的相似度 mse_loss = F.mse_loss(generated_image, target_image) psnr_score = psnr(target_image, generated_image, data_range=target_image.max() - target_image.min()) # 计算结构相似性 ssim_score = ssim(target_image, generated_image, multichannel=True) # 计算语义级别的相似度 # 定义输入张量x和生成的张量y x = ... y = ... # 加载预训练的语义分割网络 semantic_segmentation_model = ... # 计算语义分割结果 x_semantic = semantic_segmentation_model(x).detach().cpu().numpy() y_semantic = semantic_segmentation_model(y).detach().cpu().numpy() # 计算IoU指标 intersection = np.logical_and(x_semantic, y_semantic).sum() union = np.logical_or(x_semantic, y_semantic).sum() iou_score = intersection / union # 输出评价结果 print("MSE loss:", mse_loss.item()) print("PSNR score:", psnr_score) print("SSIM score:", ssim_score) print("IoU score:", iou_score) ``` 其,MSE损失函数用于评价生成图像和目标图像在像素级别上的相似度;PSNR指标用于评价图像的噪声水平,它是MSE的一种衍生量;SSIM指标用于评价生成图像和目标图像在结构上的相似度;IoU指标用于评价生成图像和目标图像在语义上的相似度,它是语义分割任务常用的评价指标。在代码,语义分割网络使用预训练的语义分割网络,可以使用任何适合的语义分割网络进行评价。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReedswayYuH.C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值