多尺度结构相似性L1损失
SSIM
结构相似性指数(Structural Similarity Index, SSIM)是一种用于评估两幅图像之间相似性的图像质量度量方法,SSIM被广泛用于图像质量评估、压缩算法的性能评估、图像增强和复原等应用中:
人眼感知两张图像相似主要基于三个方面:
- 亮度(Luminance):评估两张图像的明暗特征和亮度成分是否一致
- 对比度(Contrast):评估两张图像中不同区域之间的亮度差异程度
- 结构(Structure):评估两张图像中的纹理和细节,以及像素之间的相对位置差异
同理,SSIM的计算也是基于以上三个方面,并通过量化度量生成一个介于-1到1之间的值。越接近1两张图像越相似,反之则越不相似。
SSIM计算
- 亮度: 通过计算所有像素值的平均值得到图像的亮度量化值,公式如下
μ x = 1 N ∑ i = 1 N x i \mu_x = \frac{1}{N}\sum_{i=1}^{N}x_i μx=N1i=1∑Nxi
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+C_1} l(x,y)=μx2+μy2+C12μxμy+C1
其中l(x,y)为两张图像x和y的亮度差异值,C_1为常数。
-
对比度:通过计算所有像素的标准差得到图像的对比度量化值,公式如下
σ x = 1 N − 1 ∑ i = 1 N ( x i − μ x ) 2 \sigma_x=\sqrt{\frac{1}{N-1}\sum_{i=1}^{N}(x_i-\mu_x)^2} σx=N−11i=1∑N(xi−μx)2c ( x , y ) = 2 σ x σ y + C 2 σ x 2 + σ y 2 + C 2 c(x,y) = \frac{2\sigma_x\sigma_y+C_2}{\sigma_x^2+\sigma_y^2+C_2} c(x,y)=σx2+σy2+C22σxσy+C2
其中c(x,y)为两种图像x和y的对比度差异值,C_2为常数。
-
结构:通过计算两张图像的协方差和标准差得到图像的结构量化值,公式如下
σ x y = 1 N − 1 ∑ i = 1 N ( x i − μ x ) ( y i − μ x ) \sigma_{xy}=\frac{1}{N-1}\sum_{i=1}^{N}{(x_i-\mu_x)(y_i-\mu_x)} σxy=N−11i=1∑N(xi−μx)(yi−μx)
s ( x , y ) = σ x y + C 3 σ x σ y + C 3 s(x,y)=\frac{\sigma_{xy}+C_3}{\sigma_x\sigma_y+C_3} s(x,y)=σxσy+C3σxy+C3
其中s(x,y)表示为两张图像的结构差异值,C3为常数。
-
SSIM值
最后将三个度量相称得到最后的SSIM值
S S I M ( x , y ) = l ( x , y ) ∗ c ( x , y ) ∗ s ( x , y ) SSIM(x,y)=l(x,y)*c(x,y)*s(x,y) SSIM(x,y)=l(x,y)∗c(x,y)∗s(x,y)
如果设置常数C3 = C2/2, 通过化简可以得到公式:
S
S
I
M
(
x
,
y
)
=
(
2
μ
x
μ
y
+
C
1
)
(
2
σ
x
y
+
C
2
)
(
μ
x
2
+
μ
y
2
+
C
1
)
(
σ
x
2
+
σ
y
2
+
C
2
)
SSIM(x,y)=\frac{(2\mu_x\mu_y+C_1)(2\sigma_{xy}+C_2)}{(\mu_x^2+\mu_y^2+C_1)(\sigma_x^2+\sigma_y^2+C_2)}
SSIM(x,y)=(μx2+μy2+C1)(σx2+σy2+C2)(2μxμy+C1)(2σxy+C2)
这样我们只需要计算一下五个值就可以的到SSIM值了
μ
x
,
μ
y
,
σ
x
,
σ
y
,
σ
x
y
\mu_x,\mu_y,\sigma_x,\sigma_y,\sigma_{xy}
μx,μy,σx,σy,σxy
局部SSIM
因为人类在同一时间只能关注到局部的亮度、对比度,结构等相似度信息,因此实际代码中不计算全局的均值和方差,只计算局部窗口内的均值和方差,最后将所有局部窗口得到的量化值相加求平均得到最终的SSIM值。
公式则变为:
μ
x
=
∑
i
=
1
N
w
i
x
i
\mu_x = \sum_{i=1}^{N}{w_ix_i}
μx=i=1∑Nwixi
σ x = ∑ i = 1 N w i ( x i − μ x ) 2 \sigma_x=\sqrt{\sum_{i=1}^{N}w_i(x_i-\mu_x)^2} σx=i=1∑Nwi(xi−μx)2
σ x y = ∑ i = 1 N w i ( x i − μ x ) ( y i − μ x ) \sigma_{xy}=\sum_{i=1}^{N}w_i{(x_i-\mu_x)(y_i-\mu_x)} σxy=i=1∑Nwi(xi−μx)(yi−μx)
其中w_i是一个各个方向对称的高斯核,内部参数值采样自高斯分布,所有值加起来和为1.
定义代码如下:
coords = torch.arange(size) - (size//2)
g = torch.exp(-(coords ** 2) / (2 * sigma ** 2)) # 声明长度为size, 标准差为sigma的的一维高斯核
1_d_gauss_vec = g/g.sum() # 除以总和,保证所有值加起来和为1
2_d_gauss_vec = torch.outer(1_d_gauss_vec, 1_d_gauss_vec) # 声明size*size的二维高斯核
可视化后是这样的:
根据4.节,在实际代码中,我们只需计算五个值,其中两张图像的局部均值代码如下:
mux = F.conv2d(x, self.g_masks, groups=3, padding=self.pad)
muy = F.conv2d(y, self.g_masks, groups=3, padding=self.pad)
根据以下推理,方差可以重新计算为:
即:
σ
x
2
=
∑
i
N
w
i
x
i
2
−
μ
x
2
\sigma_x^2=\sum_{i}^{N}w_ix_i^2-\mu_x^2
σx2=i∑Nwixi2−μx2
σ x y = ∑ i N w i ( x i y i ) − μ x μ y \sigma_{xy}=\sum_{i}^{N}w_i(x_iy_i)-\mu_x\mu_y σxy=i∑Nwi(xiyi)−μxμy
以上形式的方差可以用代码表示了,如下:
sigmax2 = F.conv2d(x * x, self.g_masks, groups=3, padding=self.pad) - mux2
sigmay2 = F.conv2d(y * y, self.g_masks, groups=3, padding=self.pad) - muy2
sigmaxy = F.conv2d(x * y, self.g_masks, groups=3, padding=self.pad) - muxy
多尺度SSIM
多尺度SSIM是在原始SSIM基础上,计算多个尺度上的SSIM值,最后相乘得到最终的多尺度SSIM值。一般计算5层多尺度SSIM值。
注意亮度度量只在最后一层计算。这个过程通过设置不同sigma值的高斯核实现,可视化多尺度高斯核结果如下:
共有五行,表示不同尺度下的高斯核。三列表示高斯核作用在图像的三个通道上。可以看到,不同尺度的高斯核具有不同的聚焦视野,这是模拟人类在不同观看条件下的视觉辨别能力。
损失函数
将SSIM作为损失函数可以用来优化图像复原,图像压缩等任务。而L1损失能够最小化图像之间的绝对差异,结合多尺度SSIM和L1损失可以在某些多任务目标优化上具有更好的效果。代码如下:
loss_l1 = F.l1_loss(x, y)
loss_ms_ssim = 1 - ms_ssim_socre
total_loss = alpha * loss_ms_ssim + (1 - alpha) * loss_l1
其中alpha用于控制不同损失的重要性。
效果
计算不同图片之间的MS_SSIM_L1_Loss,如下: