SSIM是结构相似性度量,是一种衡量两个图像相似性的指标,在深度学习中,SSIm唱用来评估生成模型如(GAN)生成的图像和真实图像之间的相似度。
在图示中,我们可以观察到相同的MSE和不同的SSIM图片的清晰度差别很大,可以直观的看出,SSIM相比MSE来讲是一项更好的评价指标。
SSIM计算公式
SSIM在计算的时候主要由图片的3个关键特征决定,分别是:亮度,对比度,结构
1、亮度
图片的亮度是图像像素值大小的一种描述,对于单个像素值而言,像素值越大,就越接近白色,也就越亮,反之越暗。所有像素的平均值越大,整张图像就越亮,反之越暗。
亮度以平均灰度衡量,通过平均所有像素的值得到:
2、对比度
图像的对比度是图像像素值在整个动态范围内分布情况的一种描述,图像像素值在动态范围内分布地域宽广,对比度就越好;反之图像像素值分布的越紧凑,对比度就差,这种分布范围的描述恰恰就对应于方差或标准差的概念
3、结构
结构以像素的线性相关性来进行描述。我们通过求取协方差来得到对应结构的项:
4、SSIM最终计算公式
4、torch实现 SSIM
def calculate_ssim(img1, img2, border=0):
'''calculate SSIM
the same outputs as MATLAB's
img1, img2: [0, 255]
'''
if not img1.shape == img2.shape:
raise ValueError('Input images must have the same dimensions.')
h, w = img1.shape[:2]
img1 = img1[border:h-border, border:w-border]
img2 = img2[border:h-border, border:w-border]
if img1.ndim == 2:
return ssim(img1, img2)
elif img1.ndim == 3:
if img1.shape[2] == 3:
ssims = []
for i in range(3):
ssims.append(ssim(img1, img2))
return np.array(ssims).mean()
elif img1.shape[2] == 1:
return ssim(np.squeeze(img1), np.squeeze(img2))
else:
raise ValueError('Wrong input image dimensions.')
def ssim(img1, img2):
C1 = (0.01 * 255)**2
C2 = (0.03 * 255)**2
img1 = img1.astype(np.float64)
img2 = img2.astype(np.float64)
kernel = cv2.getGaussianKernel(11, 1.5)
window = np.outer(kernel, kernel.transpose())
mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5] # valid
mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
mu1_sq = mu1**2
mu2_sq = mu2**2
mu1_mu2 = mu1 * mu2
sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq
sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq
sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2
ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) *
(sigma1_sq + sigma2_sq + C2))
return ssim_map.mean()