PSNR和SSIM计算的代码实现

PSNR和SSIM计算的代码实现

注意:
1.以下参数img的数据类型为:numpy.ndarray
2.img的维度为:[H,W,C]
3.像素值范围在【0-255】

  • PSNR
def calculate_psnr(img1, img2):
    # img1 and img2 have range [0, 255]
    img1 = img1.astype(np.float64)
    img2 = img2.astype(np.float64)
    # print(img1)
    # print('img1-2')
    # print(img2)
    mse = np.mean((img1 - img2)**2)
    # print(mse)
    if mse == 0:
        return float('inf')
    return 20 * math.log10(255.0 / math.sqrt(mse))

  • SSIM
def ssim(img1, img2):
    C1 = (0.01 * 255)**2
    C2 = (0.03 * 255)**2

    img1 = img1.astype(np.float64)
    img2 = img2.astype(np.float64)
    kernel = cv2.getGaussianKernel(11, 1.5)
    window = np.outer(kernel, kernel.transpose())

    mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5]  # valid
    mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
    mu1_sq = mu1**2
    mu2_sq = mu2**2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq
    sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq
    sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2

    ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) *
                                                            (sigma1_sq + sigma2_sq + C2))
    return ssim_map.mean()


def calculate_ssim(img1, img2):
    '''calculate SSIM
    the same outputs as MATLAB's
    img1, img2: [0, 255]
    '''
    if not img1.shape == img2.shape:
        raise ValueError('Input images must have the same dimensions.')
    if img1.ndim == 2:
        return ssim(img1, img2)
    elif img1.ndim == 3:
        if img1.shape[2] == 3:
            ssims = []
            for i in range(3):
                ssims.append(ssim(img1, img2))
            return np.array(ssims).mean()
        elif img1.shape[2] == 1:
            return ssim(np.squeeze(img1), np.squeeze(img2))
    else:
        raise ValueError('Wrong input image dimensions.')
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面给出Python代码实现PSNRSSIM计算。 首先,我们需要导入相关的库:numpy、scipy和opencv-python。 ```python import cv2 import numpy as np from scipy import signal from scipy.ndimage import gaussian_filter ``` 接着,我们定义计算PSNR的函数psnr(): ```python def psnr(img1, img2): mse = np.mean((img1 - img2) ** 2) if mse == 0: return 100.0 PIXEL_MAX = 255.0 return 20 * np.log10(PIXEL_MAX / np.sqrt(mse)) ``` 其中,img1和img2分别为两张图片,函数返回它们的PSNR值。 然后,我们定义计算SSIM的函数ssim(): ```python def ssim(img1, img2, K=0.01, window_size=11, sigma=1.5): img1 = img1.astype(np.float64) img2 = img2.astype(np.float64) window = _gaussian_window(window_size, sigma) K1 = K ** 2 K2 = K ** 2 L = 255 C1 = (K1 * L) ** 2 C2 = (K2 * L) ** 2 mu1 = signal.convolve2d(img1, window, mode='valid') / np.sum(window) mu2 = signal.convolve2d(img2, window, mode='valid') / np.sum(window) mu1_sq = mu1 ** 2 mu2_sq = mu2 ** 2 mu1_mu2 = mu1 * mu2 sigma1_sq = signal.convolve2d(img1 ** 2, window, mode='valid') / np.sum(window) - mu1_sq sigma2_sq = signal.convolve2d(img2 ** 2, window, mode='valid') / np.sum(window) - mu2_sq sigma12 = signal.convolve2d(img1 * img2, window, mode='valid') / np.sum(window) - mu1_mu2 ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)) return np.mean(ssim_map) ``` 其中,img1和img2分别为两张图片,K、window_size和sigma是SSIM算法中的参数。函数返回它们的SSIM值。 最后,我们定义一个辅助函数_gaussian_window(),用于生成高斯窗口: ```python def _gaussian_window(window_size, sigma): gaussian = np.zeros((window_size, window_size), dtype=np.float64) center = window_size // 2 for i in range(window_size): for j in range(window_size): gaussian[i, j] = np.exp(-0.5 * ((i - center) ** 2 + (j - center) ** 2) / sigma ** 2) return gaussian / np.sum(gaussian) ``` 现在,我们可以用psnr()和ssim()函数来计算两张图片之间的PSNRSSIM了。 例如,下面的代码演示了如何计算两张图片image1和image2之间的PSNRSSIM: ```python image1 = cv2.imread('image1.jpg') image2 = cv2.imread('image2.jpg') print('PSNR:', psnr(image1, image2)) print('SSIM:', ssim(image1, image2)) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

下酒番陪绅士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值