Skip to content

Commit cb52dff

Browse files
authored
Update README.md
- Update the comparison example of our method with two other commonly used libraries.
1 parent d2c3b12 commit cb52dff

File tree

1 file changed

+57
-33
lines changed

1 file changed

+57
-33
lines changed

README.md

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,74 +10,97 @@ At the same time, in this implementation, I have dealt with the problem that the
1010

1111
> When comparing images, the mean squared error (MSE)–while simple to implement–is not highly indicative of perceived similarity. Structural similarity aims to address this shortcoming by taking texture into account. More details can be seen at https://scikit-image.org/docs/dev/auto_examples/transform/plot_ssim.html?highlight=structure+similarity
1212
13-
![results](https://user-images.githubusercontent.com/26847524/174805728-81e8502b-2ecb-4b40-a2c4-b4f1e2361ea9.png)
13+
![results](https://user-images.githubusercontent.com/26847524/175031400-92426661-4536-43c7-8f6e-5c470fb9ccb5.png)
1414

1515
```python
1616
import matplotlib.pyplot as plt
1717
import numpy as np
1818
import torch
1919
import torch.nn.functional as F
20-
from pytorch_ssim import SSIM, ssim
20+
from lartpang_ssim import SSIM
21+
from po_hsun_su_ssim import SSIM as PoHsunSuSSIM
22+
from vainf_ssim import MS_SSIM as VainFMSSSIM
23+
from vainf_ssim import SSIM as VainFSSIM
2124
from skimage import data, img_as_float
2225

2326
img = img_as_float(data.camera())
2427
rows, cols = img.shape
2528

26-
noise = np.ones_like(img) * 0.2 * (img.max() - img.min())
29+
noise = np.ones_like(img) * 0.3 * (img.max() - img.min())
2730
rng = np.random.default_rng()
2831
noise[rng.random(size=noise.shape) > 0.5] *= -1
2932

3033
img_noise = img + noise
31-
img_const = img + abs(noise)
34+
img_const = np.zeros_like(img)
3235

3336
img_tensor = torch.from_numpy(img).unsqueeze(0).unsqueeze(0).float()
3437
img_noise_tensor = torch.from_numpy(img_noise).unsqueeze(0).unsqueeze(0).float()
3538
img_const_tensor = torch.from_numpy(img_const).unsqueeze(0).unsqueeze(0).float()
3639

37-
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8), sharex=True, sharey=True)
40+
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 7))
3841
ax = axes.ravel()
3942

4043
mse_none = F.mse_loss(img_tensor, img_tensor, reduction="mean")
41-
ssim_none = ssim(img_tensor, img_tensor, L=img_tensor.max() - img_tensor.min())
42-
4344
mse_noise = F.mse_loss(img_tensor, img_noise_tensor, reduction="mean")
44-
ssim_noise = ssim(img_tensor, img_noise_tensor, L=img_noise_tensor.max() - img_noise_tensor.min())
45-
4645
mse_const = F.mse_loss(img_tensor, img_const_tensor, reduction="mean")
47-
ssim_const = ssim(img_tensor, img_const_tensor, L=img_const_tensor.max() - img_const_tensor.min())
46+
47+
# https://github.com/VainF/pytorch-msssim
48+
vainf_ssim_none = VainFSSIM(channel=1, data_range=1)(img_tensor, img_tensor)
49+
vainf_ssim_noise = VainFSSIM(channel=1, data_range=1)(img_tensor, img_noise_tensor)
50+
vainf_ssim_const = VainFSSIM(channel=1, data_range=1)(img_tensor, img_const_tensor)
51+
vainf_ms_ssim_none = VainFMSSSIM(channel=1, data_range=1)(img_tensor, img_tensor)
52+
vainf_ms_ssim_noise = VainFMSSSIM(channel=1, data_range=1)(img_tensor, img_noise_tensor)
53+
vainf_ms_ssim_const = VainFMSSSIM(channel=1, data_range=1)(img_tensor, img_const_tensor)
54+
55+
# use the settings of https://github.com/VainF/pytorch-msssim
56+
ssim_none_0 = SSIM(return_msssim=False, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_tensor)
57+
ssim_noise_0 = SSIM(return_msssim=False, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_noise_tensor)
58+
ssim_const_0 = SSIM(return_msssim=False, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_const_tensor)
59+
ms_ssim_none_0 = SSIM(return_msssim=True, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_tensor)
60+
ms_ssim_noise_0 = SSIM(return_msssim=True, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_noise_tensor)
61+
ms_ssim_const_0 = SSIM(return_msssim=True, L=1, padding=0, ensemble_kernel=False)(img_tensor, img_const_tensor)
62+
63+
# https://github.com/Po-Hsun-Su/pytorch-ssim
64+
pohsunsu_ssim_none = PoHsunSuSSIM()(img_tensor, img_tensor)
65+
pohsunsu_ssim_noise = PoHsunSuSSIM()(img_tensor, img_noise_tensor)
66+
pohsunsu_ssim_const = PoHsunSuSSIM()(img_tensor, img_const_tensor)
67+
68+
# use the settings of https://github.com/Po-Hsun-Su/pytorch-ssim
69+
ssim_none_1 = SSIM(return_msssim=False, L=1, padding=None, ensemble_kernel=True)(img_tensor, img_tensor)
70+
ssim_noise_1 = SSIM(return_msssim=False, L=1, padding=None, ensemble_kernel=True)(img_tensor, img_noise_tensor)
71+
ssim_const_1 = SSIM(return_msssim=False, L=1, padding=None, ensemble_kernel=True)(img_tensor, img_const_tensor)
72+
4873

4974
ax[0].imshow(img, cmap=plt.cm.gray, vmin=0, vmax=1)
50-
ax[0].set_xlabel(f"MSE: {mse_none:.2f}, SSIM: {ssim_none:.2f}")
75+
ax[0].set_xlabel(
76+
f"MSE: {mse_none:.6f}\n"
77+
f"SSIM {ssim_none_0:.6f}, MS-SSIM {ms_ssim_none_0:.6f}\n"
78+
f"(VainF) SSIM: {vainf_ssim_none:.6f}, MS-SSIM {vainf_ms_ssim_none:.6f}\n"
79+
f"SSIM {ssim_none_1:.6f}\n"
80+
f"(PoHsunSu) SSIM: {pohsunsu_ssim_none:.6f}\n"
81+
)
5182
ax[0].set_title("Original image")
5283

5384
ax[1].imshow(img_noise, cmap=plt.cm.gray, vmin=0, vmax=1)
54-
ax[1].set_xlabel(f"MSE: {mse_noise:.2f}, SSIM: {ssim_noise:.2f}")
85+
ax[1].set_xlabel(
86+
f"MSE: {mse_noise:.6f}\n"
87+
f"SSIM {ssim_noise_0:.6f}, MS-SSIM {ms_ssim_noise_0:.6f}\n"
88+
f"(VainF) SSIM: {vainf_ssim_noise:.6f}, MS-SSIM {vainf_ms_ssim_noise:.6f}\n"
89+
f"SSIM {ssim_noise_1:.6f}\n"
90+
f"(PoHsunSu) SSIM: {pohsunsu_ssim_noise:.6f}\n"
91+
)
5592
ax[1].set_title("Image with noise")
5693

5794
ax[2].imshow(img_const, cmap=plt.cm.gray, vmin=0, vmax=1)
58-
ax[2].set_xlabel(f"MSE: {mse_const:.2f}, SSIM: {ssim_const:.2f}")
95+
ax[2].set_xlabel(
96+
f"MSE: {mse_const:.6f}\n"
97+
f"SSIM {ssim_const_0:.6f}, MS-SSIM {ms_ssim_const_0:.6f}\n"
98+
f"(VainF) SSIM: {vainf_ssim_const:.6f}, MS-SSIM {vainf_ms_ssim_const:.6f}\n"
99+
f"SSIM {ssim_const_1:.6f}\n"
100+
f"(PoHsunSu) SSIM: {pohsunsu_ssim_const:.6f}\n"
101+
)
59102
ax[2].set_title("Image plus constant")
60103

61-
mse_none = F.mse_loss(img_tensor, img_tensor, reduction="mean")
62-
ssim_none = SSIM(L=img_tensor.max() - img_tensor.min())(img_tensor, img_tensor)
63-
64-
mse_noise = F.mse_loss(img_tensor, img_noise_tensor, reduction="mean")
65-
ssim_noise = SSIM(L=img_noise_tensor.max() - img_noise_tensor.min())(img_tensor, img_noise_tensor)
66-
67-
mse_const = F.mse_loss(img_tensor, img_const_tensor, reduction="mean")
68-
ssim_const = SSIM(L=img_const_tensor.max() - img_const_tensor.min())(img_tensor, img_const_tensor)
69-
70-
ax[3].imshow(img, cmap=plt.cm.gray, vmin=0, vmax=1)
71-
ax[3].set_xlabel(f"MSE: {mse_none:.2f}, SSIM: {ssim_none:.2f}")
72-
ax[3].set_title("Original image")
73-
74-
ax[4].imshow(img_noise, cmap=plt.cm.gray, vmin=0, vmax=1)
75-
ax[4].set_xlabel(f"MSE: {mse_noise:.2f}, SSIM: {ssim_noise:.2f}")
76-
ax[4].set_title("Image with noise")
77-
78-
ax[5].imshow(img_const, cmap=plt.cm.gray, vmin=0, vmax=1)
79-
ax[5].set_xlabel(f"MSE: {mse_const:.2f}, SSIM: {ssim_const:.2f}")
80-
ax[5].set_title("Image plus constant")
81104

82105
[ax[i].set(xticklabels=[], yticklabels=[], xticks=[], yticks=[]) for i in range(len(axes))]
83106

@@ -247,5 +270,6 @@ plt.savefig("prediction.png")
247270
## Reference
248271

249272
- https://github.com/Po-Hsun-Su/pytorch-ssim
273+
- https://github.com/VainF/pytorch-msssim
250274
- https://scikit-image.org/docs/dev/auto_examples/transform/plot_ssim.html?highlight=structure+similarity
251275
- Z. Wang, A. C. Bovik, H. R. Sheikh and E. P. Simoncelli, “Image quality assessment: From error visibility to structural similarity,” IEEE Transactions on Image Processing, vol. 13, no. 4, pp. 600-612, Apr. 2004.

0 commit comments

Comments
 (0)