make suggested naming changes in simple_metrics.py

This commit is contained in:
Gregory R. Lee
2016-01-28 22:09:52 -05:00
parent 0f71278a10
commit 8483a62e76
3 changed files with 39 additions and 37 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ 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 mse, nrmse, psnr
from .simple_metrics import mean_squared_error, normalized_root_mse, psnr
from ._structural_similarity import structural_similarity
from ._polygon import approximate_polygon, subdivide_polygon
from ._pnpoly import points_in_poly, grid_points_in_poly
@@ -36,6 +36,6 @@ __all__ = ['find_contours',
'label',
'points_in_poly',
'grid_points_in_poly',
'mse',
'nrmse',
'mean_squared_error',
'normalized_root_mse',
'psnr']
+24 -23
View File
@@ -3,48 +3,49 @@ from __future__ import division
import numpy as np
from ..util.dtype import dtype_range
__all__ = ['mse', 'nrmse', 'psnr']
__all__ = ['mean_squared_error', 'normalized_root_mse', 'psnr']
def _assert_compatible(X, Y):
def _assert_compatible(im1, im2):
"""Raise an error if the shape and dtype do not match."""
if not X.dtype == Y.dtype:
if not im1.dtype == im2.dtype:
raise ValueError('Input images must have the same dtype.')
if not X.shape == Y.shape:
if not im1.shape == im2.shape:
raise ValueError('Input images must have the same dimensions.')
return
def _as_floats(X, Y):
"""Promote X, Y to floating point precision."""
if X.dtype != np.float64:
X = X.astype(np.float64)
if Y.dtype != np.float64:
Y = Y.astype(np.float64)
return X, Y
def _as_floats(im1, im2):
"""Promote im1, im2 to floating point precision."""
if im1.dtype != np.float64:
im1 = im1.astype(np.float64)
if im2.dtype != np.float64:
im2 = im2.astype(np.float64)
return im1, im2
def mse(X, Y):
def mean_squared_error(im1, im2):
"""Compute the mean-squared error between two images.
Parameters
----------
X, Y : ndarray
im1, im2 : ndarray
Image. Any dimensionality.
Returns
-------
mse : float
The MSE metric.
The mean-squared error (MSE) metric.
"""
_assert_compatible(X, Y)
X, Y = _as_floats(X, Y)
return np.square(X - Y).mean()
_assert_compatible(im1, im2)
im1, im2 = _as_floats(im1, im2)
return np.mean(np.square(im1 - im2))
def nrmse(im_true, im_test, norm_type='Euclidean'):
"""Compute the normalized root mean-squared error between two images.
def normalized_root_mse(im_true, im_test, norm_type='Euclidean'):
"""Compute the normalized root mean-squared error (NRMSE) between two
images.
Parameters
----------
@@ -76,14 +77,14 @@ def nrmse(im_true, im_test, norm_type='Euclidean'):
norm_type = norm_type.lower()
if norm_type == 'euclidean':
denom = np.sqrt((im_true*im_true).mean())
denom = np.sqrt(np.mean((im_true*im_true)))
elif norm_type == 'min-max':
denom = im_true.max() - im_true.min()
elif norm_type == 'mean':
denom = im_true.mean()
else:
raise ValueError("Unsupported norm_type")
return np.sqrt(mse(im_true, im_test)) / denom
return np.sqrt(mean_squared_error(im_true, im_test)) / denom
def psnr(im_true, im_test, dynamic_range=None):
@@ -113,7 +114,7 @@ def psnr(im_true, im_test, dynamic_range=None):
_assert_compatible(im_true, im_test)
if dynamic_range is None:
dmin, dmax = dtype_range[im_true.dtype.type]
true_min, true_max = im_true.min(), im_true.max()
true_min, true_max = np.min(im_true), np.max(im_true)
if true_max > dmax or true_min < dmin:
raise ValueError(
"im_true has intensity values outside the range expected for "
@@ -126,5 +127,5 @@ def psnr(im_true, im_test, dynamic_range=None):
im_true, im_test = _as_floats(im_true, im_test)
err = mse(im_true, im_test)
err = mean_squared_error(im_true, im_test)
return 10 * np.log10((dynamic_range ** 2) / err)
+12 -11
View File
@@ -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, nrmse, mse
from skimage.measure import psnr, normalized_root_mse, mean_squared_error
import skimage.data
np.random.seed(5)
@@ -34,26 +34,27 @@ def test_PSNR_errors():
def test_NRMSE():
x = np.ones(4)
y = np.asarray([0., 2., 2., 2.])
assert_equal(nrmse(y, x, 'mean'), 1/np.mean(y))
assert_equal(nrmse(y, x, 'Euclidean'), 1/np.sqrt(3))
assert_equal(nrmse(y, x, 'min-max'), 1/(y.max()-y.min()))
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()))
def test_NRMSE_no_int_overflow():
camf = cam.astype(np.float32)
cam_noisyf = cam_noisy.astype(np.float32)
assert_almost_equal(mse(cam, cam_noisy),
mse(camf, cam_noisyf))
assert_almost_equal(nrmse(cam, cam_noisy),
nrmse(camf, cam_noisyf))
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))
def test_NRMSE_errors():
x = np.ones(4)
assert_raises(ValueError, nrmse, x.astype(np.uint8), x.astype(np.float32))
assert_raises(ValueError, nrmse, x[:-1], x)
assert_raises(ValueError, normalized_root_mse,
x.astype(np.uint8), x.astype(np.float32))
assert_raises(ValueError, normalized_root_mse, x[:-1], x)
# invalid normalization name
assert_raises(ValueError, nrmse, x, x, 'foo')
assert_raises(ValueError, normalized_root_mse, x, x, 'foo')
if __name__ == "__main__":