PSNR

定义

峰值信噪比(Peak Signal-to-Noise Ratio,PSNR)表示了一个信号的 最大可能功率 和影响它的 噪声功率 的比值。由于许多信号都有非常宽的动态范围,因此 PSNR 常用 分贝dB)单位来表示。

对于图像来说,图像可以被看作一个 (Field),而通常情况下,场量的功率与场的 幅值(Amplitude)的平方成正比。因此 PSNR 往往被用于对图像信号重建质量的评估,其计算如下: $$ \begin{aligned} \text{MSE} &= \frac{1}{mn} \sum_{i=0}^{m-1} \sum_{j=0}^{n-1} (x_{i,j} - y_{i,j})^2 \\ \text{PSNR}(x, y) &= 10 \cdot \log_{10} (\frac{\text{MAX}^2}{\text{MSE}}) \\ \end{aligned} $$

其中 $x$ 和 $y$ 是大小为 $(m, n)$ 的图像,$\text{MAX}$ 是像素值可能的最大值(对于 8-bit 灰度图或者 24-bit RGB 图来说,$\text{MAX}$ 为 255)。

下面解答几个常见问题。

  • 为什么用 $\log_{10}$?

    因为信号的范围太宽了,如果不用对数形式的话会非常爆炸。用对数可以用很小的数字表示很大的功率比值。

  • 为什么 $\text{MAX}$ 要平方?

    因为 PSNR 算的是功率,而图像是域,其「功率」与幅值的平方成正比。

  • 为什么外面还要乘以一个 $10$?

    因为如果不乘 $10$,算出来的单位是 贝尔B),而我们经常用 分贝dB)来表示 PSNR,$1 \text{B} = 10 \text{dB}$,因此一般乘以 $10$。

Python 实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import numpy as np

def psnr_of_imgs(img1, img2):
    MAX_PSNR_LIMIT = 100
    MAX_VALUE = 255
    mse = np.mean((img1/1. - img2/1.) ** 2)
    if mse < 1e-10:
        return MAX_PSNR_LIMIT
    return 10 * np.log10(MAX_VALUE ** 2 / mse)

def psnr_of_paths(path1, path2):
    img1 = np.array(Image.open(path1))
    img2 = np.array(Image.open(path2))
    return psnr_of_imgs(img1, img2)

SSIM

(Structural Similarity)

简单形式

$$ SSIM(x, y) = \frac {(2 \mu_x\mu_y + c_1) (2 \sigma_{xy} + c_2)} {(\mu_x^2 + \mu_y^2 + c_1) (\sigma_x^2 + \sigma_y^2 + c_2)} $$

  • $\mu_x$ 和 $\mu_y$ 分别是图像 $x$、$y$ 的均值。
  • $\sigma_x^2$ 和 $\sigma_y^2$ 分别是图像 $x$、$y$ 的方差。
  • $\sigma_{xy}$ 是图像 $x$、$y$ 的协方差。
  • $c_1=(k_1L)^2$ 和 $c_2=(k_2L)^2$ 是两个用来稳定除法的变量,其中 $L$ 是像素值可能的最大值(同 PSNR 的 $MAX_I$),$k_1 = 0.01$ 和 $k_2 = 0.03$ 是人为设定的固定值。

复杂形式

$$ \begin{aligned} l(x, y) &= \frac {2\mu_x\mu_y + c1} {\mu_x^2 + \mu_y^2 + c1} &\text{(luminance)} \\ c(x, y) &= \frac {2\sigma_x\sigma_y + c2} {\sigma_x^2 + \sigma_y^2 + c2} &\text{(contrast)} \\ s(x, y) &= \frac {\sigma_{xy} + c3} {\sigma_x\sigma_y + c3} &\text{(structure)} \\ SSIM(x, y) &= l(x, y)^\alpha c(x, y)^\beta s(x, y)^\gamma \end{aligned} $$

  • 如果 $\alpha = \beta = \gamma = 1$ 且 $c_3 = \frac{c_2}{2}$,那么该公式与简单形式一致。

MS-SSIM (Multi-Scale Structural Similarity)

$$ \begin{aligned} x_1 &= x \\ y_1 &= y \\ x_j &= \operatorname{Downscale}(\operatorname{lowPass}(x_{j-1}), 2) &, j \in [2, M]\\ y_j &= \operatorname{Downscale}(\operatorname{lowPass}(y_{j-1}), 2) &, j \in [2, M]\\ l(x, y) &= \frac {2\mu_x\mu_y + c1} {\mu_x^2 + \mu_y^2 + c1} &\text{(luminance)} \\ c(x, y) &= \frac {2\sigma_x\sigma_y + c2} {\sigma_x^2 + \sigma_y^2 + c2} &\text{(contrast)} \\ s(x, y) &= \frac {\sigma_{xy} + c3} {\sigma_x\sigma_y + c3} &\text{(structure)} \\ MS\text{-}SSIM(x, y) &= l(x, y)^{\alpha M} \prod_{j=1}^M c(x_j, y_j)^{\beta_j} s(x_j, y_j)^{\gamma_j} \end{aligned} $$

参考