PSNR(Peak Signal to Noise Ratio)峰值信噪比:

是一个表示信号最大可能功率和影响它的表示精度的破坏性噪声功率的比值的工程术语。由于许多信号都有非常宽的动态范围,峰值信噪比常用对数分贝单位来表示

MSE表示当前图像X和参考图像Y的均方误差(Mean Square Error) PSNR的单位是dB,数值越大表示失真越小

  • PSNR高于40dB说明图像质量极好(即非常接近原始图像),
  • 在30—40dB通常表示图像质量是好的(即失真可以察觉但可以接受),
  • 在20—30dB说明图像质量差;
  • PSNR低于20dB图像不可接受

一般地,针对 uint8 数据,最大像素值为 255,;针对浮点型数据,最大像素值为 1。

上面是针对灰度图像的计算方法,如果是彩色图像,通常有三种方法来计算。

  • 分别计算 RGB 三个通道的 PSNR,然后取平均值。
  • 计算 RGB 三通道的 MSE ,然后再除以 3 。
  • 将图片转化为 YCbCr 格式,然后只计算 Y 分量也就是亮度分量的 PSNR。 其中,第二和第三种方法比较常见。 PSNR基于对应像素点间的误差,是使用最广泛的一种图像客观评价指标,但未考虑人眼的视觉识别感知特性,常出现评价结果和人主观感觉不一样的情况。
##使用Scikit-Image库

# img1 和 img2 都为灰度图像,uint8 类型

# method 1
diff = img1 - img2
mse = np.mean(np.square(diff))
psnr = 10 * np.log10(255 * 255 / mse)

# method 2
psnr = skimage.measure.compare_psnr(img1, img2, 255)

代码:

def psnr(img1, img2):
   mse = np.mean( (img1/255. - img2/255.) ** 2 )
   if mse < 1.0e-10:
      return 100
   PIXEL_MAX = 1
   return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))

SSIM(Structural Similarity)结构相似性:

其输入是两张图片,即要求结构相似性的两张图片。其中一张是未经压缩的无失真图像(即ground truth),另一张就是需要与无失真图片对比的图片。物体表面的亮度信息与照度和反射系数有关,且场景中的物体的结构与照度是独立的,反射系数与物体有关。我们可以通过分离照度对物体的影响来探索一张图像中的结构信息。这里,把与物体结构相关的亮度和对比度作为图像中结构信息的定义。因为一个场景中的亮度和对比度总是在变化的,所以我们可以通过分别对局部的处理来得到更精确的结果。 SSIM取值范围[0,1],值越大,表示图像失真越小

##使用Scikit-Image库
# img1 和 img2 都为灰度图像,uint8 类型
ssim = skimage.measure.compare_ssim(img1, img2, data_range=255)

代码:

import numpy as np
from PIL import Image 
from scipy.signal import convolve2d

def matlab_style_gauss2D(shape=(3,3),sigma=0.5):
    """
    2D gaussian mask - should give the same result as MATLAB's
    fspecial('gaussian',[shape],[sigma])
    """
    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() ] = 0
    sumh = h.sum()
    if sumh != 0:
        h /= sumh
    return h

def filter2(x, kernel, mode='same'):
    return convolve2d(x, np.rot90(kernel, 2), mode=mode)

def compute_ssim(im1, im2, k1=0.01, k2=0.03, win_size=11, L=255):

    if not im1.shape == im2.shape:
        raise ValueError("Input Imagees must have the same dimensions")
    if len(im1.shape) > 2:
        raise ValueError("Please input the images with 1 channel")

    M, N = im1.shape
    C1 = (k1*L)**2
    C2 = (k2*L)**2
    window = matlab_style_gauss2D(shape=(win_size,win_size), sigma=1.5)
    window = window/np.sum(np.sum(window))

    if im1.dtype == np.uint8:
        im1 = np.double(im1)
    if im2.dtype == np.uint8:
        im2 = np.double(im2)

    mu1 = filter2(im1, window, 'valid')
    mu2 = filter2(im2, window, 'valid')
    mu1_sq = mu1 * mu1
    mu2_sq = mu2 * mu2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = filter2(im1*im1, window, 'valid') - mu1_sq
    sigma2_sq = filter2(im2*im2, window, 'valid') - mu2_sq
    sigmal2 = filter2(im1*im2, window, 'valid') - mu1_mu2

    ssim_map = ((2*mu1_mu2+C1) * (2*sigmal2+C2)) / ((mu1_sq+mu2_sq+C1) * (sigma1_sq+sigma2_sq+C2))

    return np.mean(np.mean(ssim_map))

MPSNR(Mean Peak Signal to Noise Ratio)平均峰值信噪比

针对超光谱图像,我们需要针对不同波段分别计算 PSNR,然后取平均值,这个指标称为 MPSNR。

MSSIM(Mean Structural Similarity )平均结构相似性

用滑动窗将图像分为N块,加权计算每一窗口的均值、方差以及协方差,权值wij满足∑i∑jwij=1,通常采用高斯核,然后计算对应块的结构相似度SSIM,最后将平均值作为两图像的结构相似性度量。

本文链接:http://nix.pub/article/measure-image-quality/