From 03f6da135baa6fe058c7fd3c8fba88b9b13bda0f Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Thu, 2 Feb 2012 22:41:54 -0800 Subject: [PATCH] DOC: Example of structural similarity. The example is currently broken because structural_similarity does not auto-detect dynamic range. --- doc/examples/plot_ssim.py | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 doc/examples/plot_ssim.py diff --git a/doc/examples/plot_ssim.py b/doc/examples/plot_ssim.py new file mode 100644 index 00000000..761dc29c --- /dev/null +++ b/doc/examples/plot_ssim.py @@ -0,0 +1,72 @@ +''' +=========================== +Structural similarity index +=========================== + +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 +[1]_, [2]_. + +The example shows two modifications of the input image, each with the same MSE, +but with very different mean structural similarity indices. + +.. [1] Zhou Wang; Bovik, A.C.; ,"Mean squared error: Love it or leave it? A new + look at Signal Fidelity Measures," Signal Processing Magazine, IEEE, + vol. 26, no. 1, pp. 98-117, Jan. 2009. + +.. [2] 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. + +''' + +from skimage import data, color, io, exposure, img_as_float +from skimage.measure import structural_similarity as ssim + +import numpy as np + +img = img_as_float(data.camera()) +rows, cols = img.shape + +noise = np.ones_like(img) * 0.5 * (img.max() - img.min()) +noise[np.random.random(size=noise.shape) > 0.5] *= -1 + +def mse(x, y): + return np.linalg.norm(x - y) + +img_noise = img + noise +img_const = img + abs(noise) + +import matplotlib.pyplot as plt +f, (ax0, ax1, ax2) = plt.subplots(1, 3) + +mse_none = mse(img, img) +ssim_none = ssim(img, img) + +mse_noise = mse(img, img_noise) +ssim_noise = ssim(img, img_noise) + +mse_const = mse(img, img_const) +ssim_const = ssim(img, img_const) + +label = 'MSE: %2.f, SSIM: %.2f' + +ax0.imshow(img, cmap=plt.cm.gray) +ax0.set_xlabel(label % (mse_none, ssim_none)) +ax0.set_title('Original image') + +# exposure.rescale_intensity(img_noise) +img_noise -= img_noise.min() +img_noise /= img_noise.max() + +ax1.imshow(img_noise, cmap=plt.cm.gray) +ax1.set_xlabel(label % (mse_noise, ssim_noise)) +ax1.set_title('Image with noise') + +ax2.imshow(img_const, cmap=plt.cm.gray) +ax2.set_xlabel(label % (mse_const, ssim_const)) +ax2.set_title('Image plus constant') + +plt.show()