1. PSNR (Peak Signal-to-Noise Ratio) 峰值信噪比

给定一个大小为 m × n m×n m×n 的干净图像 I I I 和噪声图像 K K K,均方误差 ( M S E ) (MSE) (MSE) 定义为:

M S E = 1 m n <munderover> i = 0 m 1 </munderover> <munderover> j = 0 n 1 </munderover> [ I ( i , j ) K ( i , j ) ] 2 MSE = \frac{1}{mn}\sum_{i=0}^{m-1}\sum_{j=0}^{n-1}[I(i, j)-K(i,j)]^2 MSE=mn1i=0m1j=0n1[I(i,j)K(i,j)]2

然后 P S N R ( d B ) PSNR (dB) PSNR(dB) 就定义为:

P S N R = 10 l o g 10 ( M A X I 2 M S E ) PSNR = 10 \cdot log_{10}(\frac{MAX_I^2}{MSE}) PSNR=10log10(MSEMAXI2)

其中 M A X I 2 MAX_I^2 MAXI2 为图片可能的最大像素值。如果每个像素都由 8 位二进制来表示,那么就为 255。通常,如果像素值由 B B B 位二进制来表示,那么 M A X I = 2 B 1 MAX_I = 2^B-1 MAXI=2B1

一般地,针对 uint8 数据,最大像素值为 255,;针对浮点型数据,最大像素值为 1。

上面是针对灰度图像的计算方法,如果是彩色图像,通常有三种方法来计算。

  • 分别计算 RGB 三个通道的 PSNR,然后取平均值。
  • 计算 RGB 三通道的 MSE ,然后再除以 3 。
  • 将图片转化为 YCbCr 格式,然后只计算 Y 分量也就是亮度分量的 PSNR。

其中,第二和第三种方法比较常见。

# im1 和 im2 都为灰度图像,uint8 类型

# method 1
diff = im1 - im2
mse = np.mean(np.square(diff))
psnr = 10 * np.log10(255 * 255 / mse)

# method 2
psnr = skimage.measure.compare_psnr(im1, im2, 255)

compare_psnr(im_true, im_test, data_range=None) 函数原型可见此处

针对超光谱图像,我们需要针对不同波段分别计算 PSNR,然后取平均值,这个指标称为 MPSNR。

2. SSIM (Structural SIMilarity) 结构相似性

S S I M SSIM SSIM 公式基于样本 x x x y y y 之间的三个比较衡量:亮度 (luminance)、对比度 (contrast) 和结构 (structure)。

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
c ( 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
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

一般取 c 3 = c 2 / 2 c_3 = c_2 / 2 c3=c2/2

  • μ x \mu_x μx x x x 的均值
  • μ y \mu_y μy y y y 的均值
  • σ x 2 \sigma_x^2 σx2 x x x 的方差
  • σ y 2 \sigma_y^2 σy2 y y y 的方差
  • σ x y \sigma_{xy} σxy x x x y y y 的协方差
  • c 1 = ( k 1 L ) 2 , c 2 = ( k 2 L ) 2 c_1 = (k_1L)^2, c_2 = (k_2L)^2 c1=(k1L)2,c2=(k2L)2 为两个常数,避免除零
  • L L L 为像素值的范围, 2 B 1 2^B-1 2B1
  • k 1 = 0.01 , k 2 = 0.03 k_1=0.01, k_2=0.03 k1=0.01,k2=0.03 为默认值

那么

S S I M ( x , y ) = [ l ( x , y ) α c ( x , y ) β s ( x , y ) γ ] SSIM(x, y) = [l(x,y)^{\alpha} \cdot c(x,y)^{\beta} \cdot s(x,y)^{\gamma}] SSIM(x,y)=[l(x,y)αc(x,y)βs(x,y)γ]

α , β , γ \alpha,\beta,\gamma α,β,γ 设为 1,可以得到

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)

每次计算的时候都从图片上取一个 N × N N×N N×N 的窗口,然后不断滑动窗口进行计算,最后取平均值作为全局的 SSIM。

# im1 和 im2 都为灰度图像,uint8 类型
ssim = skimage.measure.compare_ssim(im1, im2, data_range=255)

compare_ssim(X, Y, win_size=None, gradient=False, data_range=None, multichannel=False, gaussian_weights=False, full=False, **kwargs) 函数原型可见此处

针对超光谱图像,我们需要针对不同波段分别计算 SSIM,然后取平均值,这个指标称为 MSSIM。

获取更多精彩,请关注「seniusen」!