在本文中假设所有图像均以 sRGB 颜色空间进行编码,即使用指数 $\approx 2.4$ 进行近似伽马编码。请注意,这意味着假定由本文脚本加载的图像可以直接在屏幕上按原样查看。对于两个图像A和B,每像素结构相似性指数测量的原始公式由下式给出

$$ \operatorname{SSIM}(x, y)=(l(x, y))^\alpha(c(x, y))^\beta(s(x, y))^2\qquad(1) $$

其中 A 和 B 是所有函数的输入,但为了清楚起见省略了。为了计算像素周围补丁的均值、方差和协方差,他们使用这些公式的高斯加权版本,滤波器内核为 $11 \times 11$ 像素和 $\sigma=1.5$。亮度分量 $l$ 则为

$$ l(x, y)=\frac{2 \mu_{ A } \mu_{ B }+C_1}{\mu_{ A }^2+\mu_{ B }^2+C_1}\qquad(2) $$

其中平均值 $\mu_{ A }$ 和 $\mu_{ B }$ 也是 $x, y$ 的函数,例如 $\mu_{ A }(x, y)$,但我们跳过 $(x, y)$ 支持更短的符号,对于方差 $\sigma_{ A }^2$ 和 $\sigma_{ B }^2$ 以及协方差 $\sigma_{ A B }$ 也是如此。对比分量 $c$ 是

$$ c(x, y)=\frac{2 \sigma_{ A } \sigma_{ B }+C_2}{\sigma_{ A }^2+\sigma_{ B }^2+C_2}\qquad(3) $$

最后,结构分量 $s$ 是

$$ s(x, y)=\frac{\sigma_{ A B }+C_3}{\sigma_{ A } \sigma_{ B }+C_3}\qquad(4) $$

学者们提出 $C_1=\left(K_1 L\right)^2、C_2=\left(K_2 L\right)^2$ 和 $C_3=C_2 / 2$,其中 $L=255$ 对于 8 位组件图像。此外,他们选择了 $K_1=0.01$ 和 $K_2=0.03$。如果图像的范围是$[0,1]$,我们设置$L=1$以获得相同的结果,即$C_1=K_1^2$和$C_2=K_2^2$。最后,在整个图像上汇集的平均 SSIM (MSSIM) 值是

$$ \operatorname{MSSIM}( A , B )=\frac{1}{w h} \sum_x \sum_y \operatorname{SSIM}(x, y)\qquad(5) $$

其中 $w$ 和 $h$ 是图像的宽度和高度。可以看出,$\sigma_{ A } \sigma_{ B }$ 项位于方程 3 的分子中,以及方程 4 的分母中。为了创建简化的表达式,建议使用 $\alpha=\beta=\gamma=1$ 和 $C_3=C_2 / 2$,结果是

$$ \operatorname{SSIM}(x, y)=\frac{\left(2 \mu_{ A } \mu_{ B }+C_1\right)\left(2 \sigma_{ A B }+C_2\right)}{\left(\mu_{ A }^2+\mu_{ B }^2+C_1\right)\left(\sigma_{ A }^2+\sigma_{ B }^2+C_2\right)}\qquad(6) $$

以上等从数学角度分析 SSIM 的组成部分。下面将详细讨论质量指数本身的行为。我们使用符号 $x / y$ 来表示特定灰度值的像素。例如,$128/255$对应灰度值$50.2\%$。简写形式 $x \mid y$ 指定像素大小的棋盘图案,颜色为 $x / 255$ 和 $y / 255$。字母 $b$ 和 $w$ 分别是黑色 $(0 / 255)$ 和白色 $(255/255)$ 的简写。

图1执行代码:

 isOctave = exist('OCTAVE_VERSION', 'builtin') ~= 0;
 if(isOctave)
    pkg load image;
 end
 disp("");
 disp("====================");
 disp("Results for Figure 1");
 disp("--------------------");
 ​
 ​
 srcdir = "teaser/";
 dstdir  = "result_images/";
 images = ["earthmoon"; "plants"; "i01_l95_tid2013"; "monument_awgn5"; "einstein"; "snow_leaves_contrast3"];
 ​
 for idx = 1:length(images)
     name = images(idx,:);
     srcfileprefix = strcat(srcdir, name);

     A=rgb2gray(imread(convertStringsToChars(strcat(srcfileprefix, '_reference.png'))));
     B=rgb2gray(imread(convertStringsToChars(strcat(srcfileprefix, '_test.png'))));
     [mssim_simplified, mssim, ssim_map_simplified, ssim_map, l_map, c_map, s_map] = ssimlcs(A,B);
     mssim_simplified
     float2grayred(ssim_map, strcat(dstdir, name, '_ssim.png'), 1);
     float2grayred(l_map, convertStringsToChars(strcat(dstdir, name, '_L.png')), 1);
     float2grayred(c_map, convertStringsToChars(strcat(dstdir, name, '_C.png')), 1);
     float2grayred(s_map, convertStringsToChars(strcat(dstdir, name, '_S.png')), 1);
     disp("--------------------");
 end
 disp("====================");
 ​

图2 执行代码

 isOctave = exist('OCTAVE_VERSION', 'builtin') ~= 0;
 if(isOctave)
    pkg load image;
 end

 disp("");
 disp("====================");
 disp("Results for Figure 2");
 disp("--------------------");
 ​
 A=imread('gray/gray000.png');
 B=imread('gray/gray255.png');
 if(isOctave)
   B =B .* 255;
 end
 [mssim_simplified, mssim, ssim_map_simplified, ssim_map, l_map, c_map, s_map] = ssimlcs(A,B);
 disp("MSSIM between black and white images");
 mssim_simplified
 float2grayred(ssim_map, 'result_images/luminance_minimum_ssim.png', 1);
 float2grayred(l_map, 'result_images/luminance_minimum_L.png', 1);
 float2grayred(c_map, 'result_images/luminance_minimum_C.png', 1);
 float2grayred(s_map, 'result_images/luminance_minimum_S.png', 1);
 disp("--------------------");
 ​
 A=imread('gray/gray128.png');
 B=imread('checker/checker-bw.png');
 if(isOctave)
   B =B .* 255;
 end
 [mssim_simplified, mssim, ssim_map_simplified, ssim_map, l_map, c_map, s_map] = ssimlcs(A,B);
 disp("MSSIM between gray (128/255) and a checkered image (black and white)");
 mssim_simplified
 float2grayred(ssim_map, 'result_images/contrast_minimum_ssim.png', 1);
 float2grayred(l_map, 'result_images/contrast_minimum_L.png', 1);
 float2grayred(c_map, 'result_images/contrast_minimum_C.png', 1);
 float2grayred(s_map, 'result_images/contrast_minimum_S.png', 1);
 disp("--------------------");
 ​
 A=imread('checker/checker-bw.png');
 B=imread('checker/checker-wb.png');
 if(isOctave)
   A =A .* 255;
   B =B .* 255;
 end
 ​
 [mssim_simplified, mssim, ssim_map_simplified, ssim_map, l_map, c_map, s_map] = ssimlcs(A,B);
 disp("MSSIM between gray checker and inverted checkerboard");
 mssim_simplified
 float2grayred(ssim_map, 'result_images/structure_minimum_ssim.png', 1);
 float2grayred(l_map, 'result_images/structure_minimum_L.png', 1);
 float2grayred(c_map, 'result_images/structure_minimum_C.png', 1);
 float2grayred(s_map, 'result_images/structure_minimum_S.png', 1);
 disp("====================");
 ​

图4 执行代码

 isOctave = exist('OCTAVE_VERSION', 'builtin') ~= 0;
 if(isOctave)
     pkg load image;
 end
 disp("");
 disp("====================");
 disp("Results for Figure 4");
 disp("--------------------");
 ​
 A=imread('gray/gray253.png');
 B=imread('gray/gray255.png');
 if(isOctave)
   B =B .* 255;
 end
 [mssim, ssim_map] = ssim(A,B);
 disp("MSSIM between 253/255 and 255/255: ");
 mssim
 disp("--------------------");
 ​
 A=imread('gray/gray128.png');
 B=imread('gray/gray130.png');
 [mssim, ssim_map] = ssim(A,B);
 disp("MSSIM between 128/255 and 130/255: ");
 mssim
 disp("--------------------");
 ​
 A=imread('gray/gray000.png');
 B=imread('gray/gray002.png');
 [mssim, ssim_map] = ssim(A,B);
 disp("MSSIM between 0/255 and 2/255: ");
 mssim
 disp("--------------------");
 ​
 A=imread('gray/gray222.png');
 B=imread('gray/gray255.png');
 if(isOctave)
   B =B .* 255;
 end
 [mssim, ssim_map] = ssim(A,B);
 disp("MSSIM between 222/255 and 255/255: ");
 mssim
 disp("--------------------");
 ​
 A=imread('gray/gray000.png');
 B=imread('gray/gray026.png');
 [mssim, ssim_map] = ssim(A,B);
 disp("MSSIM between 0/255 and 26/255: ");
 mssim
 ​
 disp("====================");
 ​

https://embed.notionlytics.com/wt/ZXlKM2IzSnJjM0JoWTJWVWNtRmphMlZ5U1dRaU9pSlhiRWhvWlV4VVQxbHNjMlZYV2tKbU9URndaU0lzSW5CaFoyVkpaQ0k2SWpZMVl6QXlOVEl5TWpnME9EUTBNV000Tnpjek16azNZak5tWm1RMk1UbGlJbjA9