1.4. 图像质量评价

1.4.1. 误差类

均方误差

\[{\rm MSE} = \frac{1}{MN}\sum_{i=1}^{M}\sum_{j=0}^{N}[|{\bm I}(i,j)|, |\hat{\bm I}(i, j)|]^2 \]

1.4.2. 信噪比类

\[{\rm PSNR} = 10 \log10(\frac{V_{peak}^2}{\rm MSE}) \]

1.4.3. 结构相似性度量

SSIM

结构相似性指数 (Structure SIMilarity index, SSIM) 由周等人于2004年提出 [1], 设有数据 \(x\) 和参考数据 \(y\), \(\mu_x, \mu_y\) 分别为其均值, \(\sigma_x, \sigma_y\) 分别为标准差, \(\sigma^2_x, \sigma^2_y\) 为其方差, \(\sigma_{xy}\) 为数据 \(x\) 和参考数据 \(y\) 的协方差, 用 \(l, c, s\) 分别表示亮度(luminance), 对比度(contrast) 和结构 (structure) 相似性, 则

\[\begin{aligned} l(x, y) &=\frac{2 \mu_{x} \mu_{y}+c_{1}}{\mu_{x}^{2}+\mu_{y}^{2}+c_{1}} \\ c(x, y) &=\frac{2 \sigma_{x} \sigma_{y}+c_{2}}{\sigma_{x}^{2}+\sigma_{y}^{2}+c_{2}} \\ s(x, y) &=\frac{\sigma_{x y}+c_{3}}{\sigma_{x} \sigma_{y}+c_{3}} \end{aligned} \]

其中, \(c_1 = (k_1 L)^2, c_2 = (k_2 L)^2, c_3 = c_2 / 2\), \(L\) 是数据的动态范围 (dynamic range) ( 典型的 \(L = 2 ^{\# \text { bits per pixel }}-1\)). 结构则相似性指标可表示为

\[\operatorname{SSIM}(x, y)=\left[l(x, y)^{\alpha} \cdot c(x, y)^{\beta} \cdot s(x, y)^{\gamma}\right]. \]

\(\alpha=\beta=\gamma=1\), SSIM 等价于

\[\operatorname{SSIM}(x, y)=\frac{\left(2 \mu_{x} \mu_{y}+c_{1}\right)\left(2 \sigma_{x y}+ c_{2}\right)}{\left(\mu_{x}^{2}+\mu_{y}^{2}+c_{1}\right)\left(\sigma_{x}^{2}+\sigma_{y}^{2}+c_{2}\right)} \]

MSSSIM

GSSIM

基于梯度的结构相似性 (Gradient-based Structure SIMilarity index, GSSIM) 度量方法 [2], 对SSIM中的对比度和结构度量部分做了更改, 使用数据的梯度而不是数据来计算. 对于二维图像数据, 梯度的计算可以通过 sobel 算子滤波实现. sobel算子在水平和垂直方向上可表示为

\[G_v=\left[\begin{array}{ccc}{-1} & {-2} & {-1} \\ {0} & {0} & {0} \\ {+1} & {+2} & {+1}\end{array}\right] \]
\[G_h=\left[\begin{array}{ccc}{-1} & {0} & {+1} \\ {-2} & {0} & {+2} \\ {-1} & {0} & {+1}\end{array}\right] \]

link text

1.4.4. 实验与分析

核心代码

代码 1.14 demo_python.m
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def ssim(X, Y, win=None, winsize=11, L=None, k1=0.01, k2=0.03, alpha=1, beta=1, gamma=1, isavg=True, full=False):
    r"""Structural similarity index

    Parameters
    ----------
    X : {ndarray}
        reconstructed
    Y : {ndarray}
        referenced
    win : {[type]}, optional
        [description] (the default is None, which [default_description])
    winsize : {number}, optional
        [description] (the default is 11, which [default_description])
    L : {integer}, optional
        the dynamic range of the pixel-values (typically this is :math:`2 ^{\# \text { bits per pixel }}-1`. (the default is 255)
    k1 : {number}, optional
        [description] (the default is 0.01, which [default_description])
    k2 : {number}, optional
        [description] (the default is 0.03, which [default_description])
        sizeavg : {bool}, optional
        whether to average (the default is True, which average the result)
    alpha : {number}, optional
        luminance weight (the default is 1)
    beta : {number}, optional
        contrast weight (the default is 1)
    gamma : {number}, optional
        structure weight (the default is 1)
    isavg : {bool}, optional
        IF True, return the average SSIM index of the whole iamge,
    full : {bool}, optional
        IF True, return SSIM, luminance, contrast and structure index (the default is False, which only return SSIM)
    """

    if L is None:
        _, L = get_drange(Y.dtype)

    C1 = (k1 * L)**2
    C2 = (k2 * L)**2
    C3 = C2 / 2.

    if win is None and type(winsize) is not int:
        winsize = 11
        win = _SSIM_GAUSSIAN_KERNEL_11X11
    if win is None and type(winsize) is int:
        win = create_window(winsize, 1)

    muX = convolve(X, win)
    muY = convolve(X, win)
    muXsq = muX * muX
    muYsq = muY * muY

    sigmaXsq = np.abs(convolve(X * X, win) - muXsq)
    sigmaYsq = np.abs(convolve(Y * Y, win) - muYsq)
    sigmaXY = convolve(X * Y, win) - muX * muY

    sigmaX = np.sqrt(sigmaXsq)
    sigmaY = np.sqrt(sigmaYsq)

    luminance = (2. * muX * muY + C1) / (muX * muX + muY * muY + C1)
    contrast = (2 * sigmaX * sigmaY + C2) / (sigmaXsq + sigmaYsq + C2)
    structure = (sigmaXY + C3) / (sigmaX * sigmaY + C3)

    ssim_map = (luminance**alpha) * (contrast**beta) * (structure**gamma)

    if isavg:
        ssim_map = np.mean(ssim_map)
        luminance = np.mean(luminance)
        contrast = np.mean(contrast)
        structure = np.mean(structure)

    if full:
        return ssim_map, luminance, contrast, structure
    else:
        return ssim_map