SSIM(structural similarity index)结构相似性算法原理及python实现

一、SSIM算法简介

      SSIM(structural similarity index),结构相似性,是一种衡量两幅图像相似度的指标。该指标首先由德州大学奥斯丁分校的图像和视频工程实验室(Laboratory for Image and Video Engineering)提出。SSIM使用的两张图像中,一张为未经压缩的无失真图像,另一张为失真后的图像。
标题为:Image Quality Assessment: From Error Visibility to Structural Similarity
地址为:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1284395

      与PSNR一样,SSIM也经常用作图像质量的评价。

二、SSIM算法原理

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

      算法处理的原理图如下图所示:

                   SSIM(structural similarity index)结构相似性算法原理及python实现

      由SSIM测量系统可得相似度的测量可由三种对比模块组成,分别为:亮度,对比度,结构。接下来我们将会对这三模块函数进行定义。

      首先,对于离散信号,我们以平均灰度来作为亮度测量的估计:

                                          SSIM(structural similarity index)结构相似性算法原理及python实现             (1)

       亮度对比函数l(x,y)是关于SSIM(structural similarity index)结构相似性算法原理及python实现的函数。

       然后,由测量系统知道要把平均灰度值从信号中去除,对于离散信号SSIM(structural similarity index)结构相似性算法原理及python实现,可使用标准差来做对比度估量值。

                                  SSIM(structural similarity index)结构相似性算法原理及python实现      (2)

       对比度对比函数c(x,y)就是SSIM(structural similarity index)结构相似性算法原理及python实现的函数。

       接下来,信号被自己的标准差相除,结构对比函数就被定义成SSIM(structural similarity index)结构相似性算法原理及python实现SSIM(structural similarity index)结构相似性算法原理及python实现的函数。

       最后,三个对比模块组合成一个完整的相似测量函数:

                             SSIM(structural similarity index)结构相似性算法原理及python实现       (3)

       

       S(x,y)应该满足以下三个条件:

       (1) 对称性:SSIM(structural similarity index)结构相似性算法原理及python实现

       (2) 有界性:SSIM(structural similarity index)结构相似性算法原理及python实现

       (3) 最大值唯一性:当且仅当x=y时,S(x,y)=1 。

 

       现在,我们定义三个对比函数。

       亮度对比函数:

                            SSIM(structural similarity index)结构相似性算法原理及python实现                      (4)

       常数SSIM(structural similarity index)结构相似性算法原理及python实现是为了避免SSIM(structural similarity index)结构相似性算法原理及python实现接近0时造成系统的不稳定。

       特别的,我们选择SSIM(structural similarity index)结构相似性算法原理及python实现,L为图像灰度级数,对于8-bit灰度图像,L=255,SSIM(structural similarity index)结构相似性算法原理及python实现。公式(4)满足上述三个条件。

       对比度对比函数:

                           SSIM(structural similarity index)结构相似性算法原理及python实现                        (5)

       常数SSIM(structural similarity index)结构相似性算法原理及python实现,且SSIM(structural similarity index)结构相似性算法原理及python实现。公式(5)依然满足上述三个条件。

       结构对比函数:

                           SSIM(structural similarity index)结构相似性算法原理及python实现                          (6)

       其中

                      SSIM(structural similarity index)结构相似性算法原理及python实现                   (7)

      最后把三个函数组合起来,得到SSIM指数函数:

                      SSIM(structural similarity index)结构相似性算法原理及python实现             (8)

      这里SSIM(structural similarity index)结构相似性算法原理及python实现,用来调整三个模块间的重要性。

      为了得到简化形式,设SSIM(structural similarity index)结构相似性算法原理及python实现,得到:

                     SSIM(structural similarity index)结构相似性算法原理及python实现            (9)

三、SSIM指数应用于图像质量评估

在图像质量评估之中,局部求SSIM指数的效果要好于全局。第一,图像的统计特征通常在空间中分布不均;第二,图像的失真情况在空间中也是变化的;第三,在正常视距内,人们只能将视线聚焦在图像的一个区域内,所以局部处理更符合人类视觉系统的特点;第四,局部质量检测能得到图片空间质量变化的映射矩阵,结果可服务到其他应用中。

     所以,在上述公式中,SSIM(structural similarity index)结构相似性算法原理及python实现都加入了一个8*8的方形窗,并且逐像素的遍历整幅图片。每一步计算,SSIM(structural similarity index)结构相似性算法原理及python实现和SSIM都是基于窗口内像素的,最终得到一个SSIM指数映射矩阵,由局部SSIM指数组成。然而,简单的加窗会使映射矩阵出现不良的“分块”效应。为解决这问题,我们使用11*11的对称高斯加权函数SSIM(structural similarity index)结构相似性算法原理及python实现作为加权窗口,标准差为1.5,且

                                   SSIM(structural similarity index)结构相似性算法原理及python实现              (10)

 

SSIM(structural similarity index)结构相似性算法原理及python实现的估计值表示为:

                                 SSIM(structural similarity index)结构相似性算法原理及python实现              (11)

                         SSIM(structural similarity index)结构相似性算法原理及python实现         (12)

                          SSIM(structural similarity index)结构相似性算法原理及python实现     (13)

       应用这种加窗方法,映射矩阵就可展现出局部各向同性的性质。

       在这里,经过一些实验总结,我们把K1设为0.01,K2设为0.03,然后用平均SSIM指数作为整幅图像的估计质量评价:

                 SSIM(structural similarity index)结构相似性算法原理及python实现   (14)

其中X,Y为图像,SSIM(structural similarity index)结构相似性算法原理及python实现为局部SSIM指数在映射中的位置,MN为局部窗口的数量。

三、python代码实现

代码是从项目里面直接贴过来的,只改了其中一些部分,代码的目录格式如下所示:

├─python-ssim
│  │  python-ssim.py
│  │  README.md
│  │  使用.txt
│  └─data
│          1.jpg
│          2.jpg
│          3.jpg
│          4.jpg
│          5.png
│          6.png
 

python-ssim.py文件

import numpy
import scipy.ndimage
from scipy.ndimage import imread
from numpy.ma.core import exp
from scipy.constants.constants import pi

img_mat_1=imread('./data/5.png', flatten=True)
img_mat_2=imread('./data/6.png', flatten=True)


'''
The function to compute SSIM
@param param: img_mat_1 1st 2D matrix
@param param: img_mat_2 2nd 2D matrix
'''
def compute_ssim(img_mat_1, img_mat_2):
    #Variables for Gaussian kernel definition
    gaussian_kernel_sigma=1.5
    gaussian_kernel_width=11
    gaussian_kernel=numpy.zeros((gaussian_kernel_width,gaussian_kernel_width))
    
    #Fill Gaussian kernel
    for i in range(gaussian_kernel_width):
        for j in range(gaussian_kernel_width):
            gaussian_kernel[i,j]=\
            (1/(2*pi*(gaussian_kernel_sigma**2)))*\
            exp(-(((i-5)**2)+((j-5)**2))/(2*(gaussian_kernel_sigma**2)))

    #Convert image matrices to double precision (like in the Matlab version)
    img_mat_1=img_mat_1.astype(numpy.float)
    img_mat_2=img_mat_2.astype(numpy.float)
    
    #Squares of input matrices
    img_mat_1_sq=img_mat_1**2
    img_mat_2_sq=img_mat_2**2
    img_mat_12=img_mat_1*img_mat_2
    
    #Means obtained by Gaussian filtering of inputs
    img_mat_mu_1=scipy.ndimage.filters.convolve(img_mat_1,gaussian_kernel)
    img_mat_mu_2=scipy.ndimage.filters.convolve(img_mat_2,gaussian_kernel)
        
    #Squares of means
    img_mat_mu_1_sq=img_mat_mu_1**2
    img_mat_mu_2_sq=img_mat_mu_2**2
    img_mat_mu_12=img_mat_mu_1*img_mat_mu_2
    
    #Variances obtained by Gaussian filtering of inputs' squares
    img_mat_sigma_1_sq=scipy.ndimage.filters.convolve(img_mat_1_sq,gaussian_kernel)
    img_mat_sigma_2_sq=scipy.ndimage.filters.convolve(img_mat_2_sq,gaussian_kernel)
    
    #Covariance
    img_mat_sigma_12=scipy.ndimage.filters.convolve(img_mat_12,gaussian_kernel)
    
    #Centered squares of variances
    img_mat_sigma_1_sq=img_mat_sigma_1_sq-img_mat_mu_1_sq
    img_mat_sigma_2_sq=img_mat_sigma_2_sq-img_mat_mu_2_sq
    img_mat_sigma_12=img_mat_sigma_12-img_mat_mu_12;
    
    #c1/c2 constants
    #First use: manual fitting
    c_1=6.5025
    c_2=58.5225
    
    #Second use: change k1,k2 & c1,c2 depend on L (width of color map)
    l=255
    k_1=0.01
    c_1=(k_1*l)**2
    k_2=0.03
    c_2=(k_2*l)**2
    
    #Numerator of SSIM
    num_ssim=(2*img_mat_mu_12+c_1)*(2*img_mat_sigma_12+c_2)
    #Denominator of SSIM
    den_ssim=(img_mat_mu_1_sq+img_mat_mu_2_sq+c_1)*\
    (img_mat_sigma_1_sq+img_mat_sigma_2_sq+c_2)
    #SSIM
    ssim_map=num_ssim/den_ssim
    index=numpy.average(ssim_map)

    print(index)

    return index

    
compute_ssim(img_mat_1, img_mat_2)

三、结果示例

示例1

SSIM(structural similarity index)结构相似性算法原理及python实现

SSIM(structural similarity index)结构相似性算法原理及python实现

SSIM(structural similarity index)结构相似性算法原理及python实现

示例2

SSIM(structural similarity index)结构相似性算法原理及python实现

SSIM(structural similarity index)结构相似性算法原理及python实现

 

SSIM(structural similarity index)结构相似性算法原理及python实现

示例3

SSIM(structural similarity index)结构相似性算法原理及python实现

SSIM(structural similarity index)结构相似性算法原理及python实现

SSIM(structural similarity index)结构相似性算法原理及python实现


参考:https://blog.****.net/ecnu18918079120/article/details/60149864SSIM指数应用于图像质量评估

https://baike.baidu.com/item/SSIM/2091025?fr=aladdin

https://blog.****.net/leviopku/article/details/84635897