图像质量评估算法SSIM(结构相似性)

您所在的位置:网站首页 matlab内置函数ssim 图像质量评估算法SSIM(结构相似性)

图像质量评估算法SSIM(结构相似性)

2024-03-28 09:39| 来源: 网络整理| 查看: 265

SSIM(structural similarity index)

由于最近在阅读图像超分辨率方面的RCAN论文,里面涉及到了两幅图像之间的相似性,所以就引入了这个指标,并最终使用pyhton进行实现。结构相似性,是一种衡量两幅图像相似度的指标。该指标首先由德州大学奥斯丁分校的图像和视频工程实验室(Laboratory for Image and Video Engineering)提出。而如果两幅图像是压缩前和压缩后的图像,那么SSIM算法就可以用来评估压缩后的图像质量。本文着重在于代码实现SSIM函数,而该算法的原理以及为什么需要高斯核函数作为模板的权值并不关心,如果需要的话可以在文章的后面大的连接里面自行阅读。

如何计算结构相似性

在计算两幅图像的结构相似性,需要高斯模板用来作为一个像素区域的概率值,进而计算得到某个区域的像素平均值,标准差,方差和协方差等概念。除此之外给出一组公式用来计算SSIM: L ( X , Y ) = 2 μ X μ Y + C 1 μ X 2 + μ Y 2 + C 1 L(X,Y) = \frac{2\mu_X \mu_Y+C_1}{\mu_X^2 + \mu_Y^2+C1} L(X,Y)=μX2​+μY2​+C12μX​μY​+C1​​ C ( X , Y ) = 2 σ X σ Y + C 2 σ 2 2 + σ Y 2 + C 2 C(X,Y) = \frac{2\sigma_X\sigma_Y+C_2}{\sigma_2^2+\sigma_Y^2+C_2} C(X,Y)=σ22​+σY2​+C2​2σX​σY​+C2​​ S ( X , Y ) = σ X Y + C 3 σ X σ Y + C 3 S(X,Y) = \frac{\sigma_{XY+C_3}}{\sigma_X\sigma_Y+C3} S(X,Y)=σX​σY​+C3σXY+C3​​​ 当里面的参数 C 3 = C 2 / 2 C_3 = C_2/2 C3​=C2​/2时 S S I M ( X , Y ) 也 可 以 写 成 下 面 的 式 子 SSIM(X,Y)也可以写成下面的式子 SSIM(X,Y)也可以写成下面的式子 S S I M ( X , Y ) = L ( X , Y ) C ( X , Y ) S ( X , Y ) = 2 μ X μ Y + C 1 μ X 2 + μ Y 2 + C 1 ∗ 2 σ X Y + C 2 σ 2 2 + σ Y 2 + C 2 SSIM(X,Y) = L(X,Y)C(X,Y)S(X,Y)=\frac{2\mu_X \mu_Y+C_1}{\mu_X^2 + \mu_Y^2+C1}* \frac{2\sigma_{XY}+C_2}{\sigma_2^2+\sigma_Y^2+C_2} SSIM(X,Y)=L(X,Y)C(X,Y)S(X,Y)=μX2​+μY2​+C12μX​μY​+C1​​∗σ22​+σY2​+C2​2σXY​+C2​​ 里面的 μ X 、 σ X \mu_X、\sigma_X μX​、σX​分别代表X这幅图片里面的均值。 下面用图示的方式演示涌口滑动的过程: 在这里插入图片描述 上图的左边是高斯核尺寸是 ( 2 k + 1 ) ∗ ( 2 k + 1 ) (2k+1)*(2k+1) (2k+1)∗(2k+1),加入我们将要从图片的第 ( i , j ) (i,j) (i,j)个位置与高斯核进行运算(如果熟悉卷积神经网络的话大家肯定就很快就可以理解)。然后我们使用高斯模块在整个图像上移动得到一个SSIM_MAP,其尺寸就是 ( w − 2 k ) ∗ ( d − 2 k ) (w-2k)*(d-2k) (w−2k)∗(d−2k)。

高斯核的实现

按照前人的做法是使用一个 ( 2 k + 1 ) ∗ ( 2 k + 1 ) (2k+1)*(2k+1) (2k+1)∗(2k+1)的高斯模板滑动整个图像得到一个SSIM_MAP之后再计算其平均值作为两幅图像的SSIM。这里需要强调的是区域里面的每个像素出现的概率是符合高斯分布的,而不是均匀分布。故我们首先要设计一个高斯核函数确定权重,计算公式如下: K ( i , j ) = 1 2 π σ 2 e x p − ( i − k ) 2 + ( j − k ) 2 2 π σ 2 , 0 ≤ i , j ≤ 2 k K(i,j) = \frac{1}{2\pi\sigma^2}exp^{-\frac{(i-k)^2+(j-k)^2}{2\pi\sigma^2}}, 0 \le i,j \le2k K(i,j)=2πσ21​exp−2πσ2(i−k)2+(j−k)2​,0≤i,j≤2k

区域平均值实现

由于区域里面的每个点具有不同的权重,在这里我们认为从图片的 ( i , j ) (i,j) (i,j)点开始与高斯核匹配的的平均值是: μ X ( i , j ) = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) X ( i + m , j + n ) \mu_X(i,j) = \Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)X(i+m,j+n) μX​(i,j)=Σm=0m=2k​Σn=0n=2k​k(m,n)X(i+m,j+n)

区域方差实现

根据方差的公式我们写作: σ X 2 ( i , j ) = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) ( X ( i + m , j + n ) − μ X ( i , j ) ) 2 = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) ( X ( i + m , j + n ) 2 − 2 X ( i + m , j + n ) μ X ( i , j ) 2 + μ X 2 ( i , j ) = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) X ( i + m , j + n ) 2 − μ X 2 ( i , j ) \sigma_X^2(i,j) = \Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)(X(i+m,j+n)-\mu_X(i,j))^2 \\=\Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)(X(i+m,j+n)^2-2X(i+m,j+n)\mu_X(i,j)^2+\mu_X^2(i,j) \\=\Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)X(i+m,j+n)^2-\mu_X^2(i,j) σX2​(i,j)=Σm=0m=2k​Σn=0n=2k​k(m,n)(X(i+m,j+n)−μX​(i,j))2=Σm=0m=2k​Σn=0n=2k​k(m,n)(X(i+m,j+n)2−2X(i+m,j+n)μX​(i,j)2+μX2​(i,j)=Σm=0m=2k​Σn=0n=2k​k(m,n)X(i+m,j+n)2−μX2​(i,j)

区域协方差实现

协方差公式: σ X , Y = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) ( X ( i + m , j + n ) − μ X ( i , j ) ) ( Y ( i + m , j + n ) − μ Y ( i , j ) ) = Σ m = 0 m = 2 k Σ n = 0 n = 2 k k ( m , n ) X ( i + m , j + n ) Y ( i + m , j + n ) − μ X ( i , j ) μ Y ( i , j ) \sigma_{X,Y} = \Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)(X(i+m,j+n)-\mu_X(i,j))(Y(i+m,j+n)-\mu_Y(i,j))\\ = \Sigma_{m=0}^{m=2k}\Sigma_{n=0}^{n=2k}k(m,n)X(i+m,j+n)Y(i+m,j+n) - \mu_X(i,j)\mu_Y(i,j) σX,Y​=Σm=0m=2k​Σn=0n=2k​k(m,n)(X(i+m,j+n)−μX​(i,j))(Y(i+m,j+n)−μY​(i,j))=Σm=0m=2k​Σn=0n=2k​k(m,n)X(i+m,j+n)Y(i+m,j+n)−μX​(i,j)μY​(i,j)

代码实现

由于上面的几部分已经将SSIM公式里面的参数计算出来了,下面就是我基于自己的理解编写出来的代码:

import numpy as np import cv2 def getres(img, kernel, i,j): k_w, k_d = kernel.shape res = np.sum(img[i:i+k_w, j:j+k_d]*kernel) return res def conv2d(img, kernel): img_w, img_d = img.shape k_w, k_d = kernel.shape res = [[getres(img, kernel, i,j) for j in range(img_d-k_d+1)] for i in range(img_w-k_w+1)] return np.array(res, dtype=np.float32) def ssim(img1=None, img2=None, k=11, sigma=1.5): #输入的图片是三通道的rgb图片格式为uint8 if img1.shape != img2.shape: print("the shape of the two image is different, please check!!!") return None if k


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3