diff --git a/skimage/measure/__init__.py b/skimage/measure/__init__.py index be5f2bd0..76760bba 100755 --- a/skimage/measure/__init__.py +++ b/skimage/measure/__init__.py @@ -2,8 +2,8 @@ from ._find_contours import find_contours from ._marching_cubes import (marching_cubes, mesh_surface_area, correct_mesh_orientation) from ._regionprops import regionprops, perimeter -from .simple_metrics import mean_squared_error, normalized_root_mse, psnr -from ._structural_similarity import structural_similarity +from .simple_metrics import compare_mse, compare_nrmse, compare_psnr +from ._structural_similarity import compare_ssim, structural_similarity from ._polygon import approximate_polygon, subdivide_polygon from ._pnpoly import points_in_poly, grid_points_in_poly from ._moments import moments, moments_central, moments_normalized, moments_hu @@ -36,6 +36,9 @@ __all__ = ['find_contours', 'label', 'points_in_poly', 'grid_points_in_poly', - 'mean_squared_error', - 'normalized_root_mse', - 'psnr'] + 'structural_similarity', + 'compare_ssim', + 'compare_mse', + 'compare_nrmse', + 'compare_psnr', + ] diff --git a/skimage/measure/_structural_similarity.py b/skimage/measure/_structural_similarity.py index 0b431a21..9e44d918 100644 --- a/skimage/measure/_structural_similarity.py +++ b/skimage/measure/_structural_similarity.py @@ -1,17 +1,19 @@ from __future__ import division -__all__ = ['structural_similarity'] +__all__ = ['compare_ssim', + 'structural_similarity'] import numpy as np from scipy.ndimage import uniform_filter, gaussian_filter from ..util.dtype import dtype_range from ..util.arraypad import crop +from .._shared.utils import deprecated -def structural_similarity(X, Y, win_size=None, gradient=False, - dynamic_range=None, multichannel=False, - gaussian_weights=False, full=False, **kwargs): +def compare_ssim(X, Y, win_size=None, gradient=False, + dynamic_range=None, multichannel=False, + gaussian_weights=False, full=False, **kwargs): """Compute the mean structural similarity index between two images. Parameters @@ -216,3 +218,13 @@ def structural_similarity(X, Y, win_size=None, gradient=False, return mssim, S else: return mssim + + +@deprecated('compare_ssim') +def structural_similarity(X, Y, win_size=None, gradient=False, + dynamic_range=None, multichannel=False, + gaussian_weights=False, full=False, **kwargs): + """""" + compare_ssim.__doc__ + return compare_ssim(X, Y, win_size=None, gradient=False, + dynamic_range=None, multichannel=False, + gaussian_weights=False, full=False, **kwargs) diff --git a/skimage/measure/simple_metrics.py b/skimage/measure/simple_metrics.py index 6083010b..e37be6a6 100644 --- a/skimage/measure/simple_metrics.py +++ b/skimage/measure/simple_metrics.py @@ -3,7 +3,10 @@ from __future__ import division import numpy as np from ..util.dtype import dtype_range -__all__ = ['mean_squared_error', 'normalized_root_mse', 'psnr'] +__all__ = ['compare_mse', + 'compare_nrmse', + 'compare_psnr', + ] def _assert_compatible(im1, im2): @@ -25,7 +28,7 @@ def _as_floats(im1, im2): return im1, im2 -def mean_squared_error(im1, im2): +def compare_mse(im1, im2): """Compute the mean-squared error between two images. Parameters @@ -44,7 +47,7 @@ def mean_squared_error(im1, im2): return np.mean(np.square(im1 - im2), dtype=np.float64) -def normalized_root_mse(im_true, im_test, norm_type='Euclidean'): +def compare_nrmse(im_true, im_test, norm_type='Euclidean'): """Compute the normalized root mean-squared error (NRMSE) between two images. @@ -85,10 +88,10 @@ def normalized_root_mse(im_true, im_test, norm_type='Euclidean'): denom = im_true.mean() else: raise ValueError("Unsupported norm_type") - return np.sqrt(mean_squared_error(im_true, im_test)) / denom + return np.sqrt(compare_mse(im_true, im_test)) / denom -def psnr(im_true, im_test, dynamic_range=None): +def compare_psnr(im_true, im_test, dynamic_range=None): """ Compute the peak signal to noise ratio (PSNR) for an image. Parameters @@ -128,5 +131,5 @@ def psnr(im_true, im_test, dynamic_range=None): im_true, im_test = _as_floats(im_true, im_test) - err = mean_squared_error(im_true, im_test) + err = compare_mse(im_true, im_test) return 10 * np.log10((dynamic_range ** 2) / err) diff --git a/skimage/measure/tests/test_simple_metrics.py b/skimage/measure/tests/test_simple_metrics.py index b59a11a8..bb827aac 100644 --- a/skimage/measure/tests/test_simple_metrics.py +++ b/skimage/measure/tests/test_simple_metrics.py @@ -2,7 +2,7 @@ import numpy as np from numpy.testing import (run_module_suite, assert_equal, assert_raises, assert_almost_equal) -from skimage.measure import psnr, normalized_root_mse, mean_squared_error +from skimage.measure import compare_psnr, compare_nrmse, compare_mse import skimage.data np.random.seed(5) @@ -16,45 +16,45 @@ def test_PSNR_vs_IPOL(): # Tests vs. imdiff result from the following IPOL article and code: # http://www.ipol.im/pub/art/2011/g_lmii/ p_IPOL = 22.4497 - p = psnr(cam, cam_noisy) + p = compare_psnr(cam, cam_noisy) assert_almost_equal(p, p_IPOL, decimal=4) def test_PSNR_float(): - p_uint8 = psnr(cam, cam_noisy) - p_float64 = psnr(cam/255., cam_noisy/255., dynamic_range=1) + p_uint8 = compare_psnr(cam, cam_noisy) + p_float64 = compare_psnr(cam/255., cam_noisy/255., dynamic_range=1) assert_almost_equal(p_uint8, p_float64, decimal=5) def test_PSNR_errors(): - assert_raises(ValueError, psnr, cam, cam.astype(np.float32)) - assert_raises(ValueError, psnr, cam, cam[:-1, :]) + assert_raises(ValueError, compare_psnr, cam, cam.astype(np.float32)) + assert_raises(ValueError, compare_psnr, cam, cam[:-1, :]) def test_NRMSE(): x = np.ones(4) y = np.asarray([0., 2., 2., 2.]) - assert_equal(normalized_root_mse(y, x, 'mean'), 1/np.mean(y)) - assert_equal(normalized_root_mse(y, x, 'Euclidean'), 1/np.sqrt(3)) - assert_equal(normalized_root_mse(y, x, 'min-max'), 1/(y.max()-y.min())) + assert_equal(compare_nrmse(y, x, 'mean'), 1/np.mean(y)) + assert_equal(compare_nrmse(y, x, 'Euclidean'), 1/np.sqrt(3)) + assert_equal(compare_nrmse(y, x, 'min-max'), 1/(y.max()-y.min())) def test_NRMSE_no_int_overflow(): camf = cam.astype(np.float32) cam_noisyf = cam_noisy.astype(np.float32) - assert_almost_equal(mean_squared_error(cam, cam_noisy), - mean_squared_error(camf, cam_noisyf)) - assert_almost_equal(normalized_root_mse(cam, cam_noisy), - normalized_root_mse(camf, cam_noisyf)) + assert_almost_equal(compare_mse(cam, cam_noisy), + compare_mse(camf, cam_noisyf)) + assert_almost_equal(compare_nrmse(cam, cam_noisy), + compare_nrmse(camf, cam_noisyf)) def test_NRMSE_errors(): x = np.ones(4) - assert_raises(ValueError, normalized_root_mse, + assert_raises(ValueError, compare_nrmse, x.astype(np.uint8), x.astype(np.float32)) - assert_raises(ValueError, normalized_root_mse, x[:-1], x) + assert_raises(ValueError, compare_nrmse, x[:-1], x) # invalid normalization name - assert_raises(ValueError, normalized_root_mse, x, x, 'foo') + assert_raises(ValueError, compare_nrmse, x, x, 'foo') if __name__ == "__main__": diff --git a/skimage/measure/tests/test_structural_similarity.py b/skimage/measure/tests/test_structural_similarity.py index 474e9901..36556dcb 100644 --- a/skimage/measure/tests/test_structural_similarity.py +++ b/skimage/measure/tests/test_structural_similarity.py @@ -4,10 +4,11 @@ import scipy.io from numpy.testing import (assert_equal, assert_raises, assert_almost_equal, assert_array_almost_equal) -from skimage.measure import structural_similarity as ssim +from skimage.measure import compare_ssim as ssim import skimage.data from skimage.io import imread from skimage import data_dir +from skimage._shared._warnings import expected_warnings np.random.seed(5) cam = skimage.data.camera() @@ -18,6 +19,16 @@ cam_noisy = cam_noisy.astype(cam.dtype) np.random.seed(1234) +# This test to be removed in 0.14, along with the structural_similarity alias +# for compare_ssim +def test_old_name_deprecated(): + from skimage.measure import structural_similarity + with expected_warnings('Call to deprecated function ' + '``structural_similarity``. Use ' + '``compare_ssim`` instead.'): + ssim_result = structural_similarity(cam, cam_noisy, win_size=32) + + def test_ssim_patch_range(): N = 51 X = (np.random.rand(N, N) * 255).astype(np.uint8)