SSIM(结构相似性)

SSIM可以抵消MSE无法衡量图像结构相似性的缺陷。

SSIM定义:

在这里插入图片描述
其中:α、β、γ均大于0
在这里插入图片描述
上式中,μ_x,μ_y为图像块所有像素;δ_x,δ_y为图像像素值的标准差;δ_xy为x与y的协方差;C_1,C_2,C_3为常数,为避免分母为0时带来的系统错误。
在实际应用中,α=β=γ=1,C_3= 0.5C_2,则SSIM表达式为:
在这里插入图片描述

SSIM性质

  1. SSIM具有对称性。即SSIM(x,y)=SSIM(y,x)
  2. SSIM是一个0到1之间的数,SSIM越大,两图像间差异越小。

tensorflow实现:

tf.image.ssim(img1,img2,max_val)
img1:第一批图片。
img2:第二批图片。
max_val:图像的动态范围(即最大允许值和最小允许值之间的差值)。

注意:真正的SSIM仅在灰度上定义。 此函数不执行任何颜色空间转换。 (如果输入已经是YUV,那么它将计算YUV SSIM平均值。)

使用python实现

import tensorflow as tf
import numpy as np
import scipy.misc
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"]='2'
def _tf_fspecial_gauss(size, sigma=1.5):
    x_data, y_data = np.mgrid[-size//2 + 1:size//2 + 1, -size//2 + 1:size//2 + 1]
    x_data = np.expand_dims(x_data, axis=-1)#扩展数组的形状
    x_data = np.expand_dims(x_data, axis=-1)

    y_data = np.expand_dims(y_data, axis=-1)
    y_data = np.expand_dims(y_data, axis=-1)

    x = tf.constant(x_data, dtype=tf.float32)
    y = tf.constant(y_data, dtype=tf.float32)

    g = tf.exp(-((x**2 + y**2)/(2.0*sigma**2)))
    return g / tf.reduce_sum(g)

def SSIM(img1, img2, k1=0.01, k2=0.02, L=1, window_size=11):
    
    img1 = tf.expand_dims(img1, 0)
    img1 = tf.expand_dims(img1, -1)
    img2 = tf.expand_dims(img2, 0)
    img2 = tf.expand_dims(img2, -1)
    
    window = _tf_fspecial_gauss(window_size)
    
    mu1 = tf.nn.conv2d(img1, window, strides = [1, 1, 1, 1], padding = 'VALID')
    mu2 = tf.nn.conv2d(img2, window, strides = [1, 1, 1, 1], padding = 'VALID')
    
    mu1_sq = mu1 * mu1
    mu2_sq = mu2 * mu2
    mu1_mu2 = mu1 * mu2
    
    sigma1_sq = tf.nn.conv2d(img1*img1, window, strides = [1 ,1, 1, 1], padding = 'VALID') - mu1_sq
    sigma2_sq = tf.nn.conv2d(img2*img2, window, strides = [1, 1, 1, 1], padding = 'VALID') - mu2_sq
    sigma1_2 = tf.nn.conv2d(img1*img2, window, strides = [1, 1, 1, 1], padding = 'VALID') - mu1_mu2
    
    c1 = (k1*L)**2
    c2 = (k2*L)**2

    ssim_map = ((2*mu1_mu2 + c1)*(2*sigma1_2 + c2)) / ((mu1_sq + mu2_sq + c1)*(sigma1_sq + sigma2_sq + c2))

    return tf.reduce_mean(ssim_map)

img1 = np.array(scipy.misc.imread('tree.png', mode='RGB').astype('float32'))
img2 = np.array(scipy.misc.imread('tree2.png', mode='RGB').astype('float32'))

img1 = tf.constant(img1)
img2 = tf.constant(img2)

_SSIM_ = tf.image.ssim(img1, img2, 1.0)
rgb1 = tf.unstack(img1, axis=2)
r1 = rgb1[0]
g1 = rgb1[1]
b1 = rgb1[2]

rgb2 = tf.unstack(img2, axis=2)
r2 = rgb2[0]
g2 = rgb2[1]
b2 = rgb2[2]

ssim_r=SSIM(r1,r2)
ssim_g=SSIM(g1,g2)
ssim_b=SSIM(b1,b2)
ssim = tf.reduce_mean(ssim_r+ssim_g+ssim_b)/3
with tf.Session() as sess:
with tf.Session() as sess:
    print('tf.image.ssim: ',sess.run(_SSIM_))
    print('SSIM: ',sess.run(ssim))

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cherry1307/article/details/88529301
今日推荐