diff --git a/skimage/filter/_tv_denoise.py b/skimage/filter/_tv_denoise.py index e8736786..4f663ae2 100644 --- a/skimage/filter/_tv_denoise.py +++ b/skimage/filter/_tv_denoise.py @@ -1,4 +1,5 @@ import numpy as np +from skimage import img_as_float def _tv_denoise_3d(im, weight=100, eps=2.e-4, n_iter_max=200): @@ -26,7 +27,7 @@ def _tv_denoise_3d(im, weight=100, eps=2.e-4, n_iter_max=200): Returns ------- out: ndarray - denoised array + denoised array of floats Notes ----- @@ -109,7 +110,7 @@ def _tv_denoise_2d(im, weight=50, eps=2.e-4, n_iter_max=200): Returns ------- out: ndarray - denoised array + denoised array of floats Notes ----- @@ -169,9 +170,8 @@ def _tv_denoise_2d(im, weight=50, eps=2.e-4, n_iter_max=200): E_previous = E i += 1 return out - - -def tv_denoise(im, weight=50, eps=2.e-4, keep_type=False, n_iter_max=200): + +def tv_denoise(im, weight=50, eps=2.e-4, n_iter_max=200): """ Perform total-variation denoising on 2-d and 3-d images @@ -192,19 +192,13 @@ def tv_denoise(im, weight=50, eps=2.e-4, keep_type=False, n_iter_max=200): (E_(n-1) - E_n) < eps * E_0 - keep_type: bool, optional (False) - whether the output has the same dtype as the input array. - keep_type is False by default, and the dtype of the output - is np.float - n_iter_max: int, optional maximal number of iterations used for the optimization. Returns ------- out: ndarray - denoised array - + denoised array of floats Notes ----- @@ -245,7 +239,7 @@ def tv_denoise(im, weight=50, eps=2.e-4, keep_type=False, n_iter_max=200): """ im_type = im.dtype if not im_type.kind == 'f': - im = im.astype(np.float) + im = img_as_float(im) if im.ndim == 2: out = _tv_denoise_2d(im, weight, eps, n_iter_max) @@ -254,7 +248,4 @@ def tv_denoise(im, weight=50, eps=2.e-4, keep_type=False, n_iter_max=200): else: raise ValueError('only 2-d and 3-d images may be denoised with this ' 'function') - if keep_type: - return out.astype(im_type) - else: - return out + return out diff --git a/skimage/filter/tests/test_tv_denoise.py b/skimage/filter/tests/test_tv_denoise.py index 4cc6adbb..635dfdcd 100644 --- a/skimage/filter/tests/test_tv_denoise.py +++ b/skimage/filter/tests/test_tv_denoise.py @@ -2,7 +2,7 @@ import numpy as np from numpy.testing import run_module_suite from skimage import filter, data, color -from skimage import img_as_uint +from skimage import img_as_uint, img_as_ubyte class TestTvDenoise(): @@ -27,12 +27,21 @@ class TestTvDenoise(): grad_denoised = ndimage.morphological_gradient( denoised_lena, size=((3, 3))) # test if the total variation has decreased + assert grad_denoised.dtype == np.float assert (np.sqrt((grad_denoised**2).sum()) < np.sqrt((grad**2).sum()) / 2) - denoised_lena_int = filter.tv_denoise(img_as_uint(lena), - weight=60.0, keep_type=True) - assert denoised_lena_int.dtype is np.dtype('uint16') + def test_tv_denoise_float_result_range(self): + # lena image + lena = color.rgb2gray(data.lena())[:256, :256] + int_lena = np.multiply(lena, 255).astype(np.uint8) + assert np.max(int_lena) > 1 + denoised_int_lena = filter.tv_denoise(int_lena, weight=60.0) + # test if the value range of output float data is within [0.0:1.0] + assert denoised_int_lena.dtype == np.float + assert np.max(denoised_int_lena) <= 1.0 + assert np.min(denoised_int_lena) >= 0.0 + def test_tv_denoise_3d(self): """ Apply the TV denoising algorithm on a 3D image representing @@ -45,13 +54,10 @@ class TestTvDenoise(): mask += 20 * np.random.randn(*mask.shape) mask[mask < 0] = 0 mask[mask > 255] = 255 - res = filter.tv_denoise(mask.astype(np.uint8), - weight=100, keep_type=True) - assert res.std() < mask.std() - assert res.dtype is np.dtype('uint8') res = filter.tv_denoise(mask.astype(np.uint8), weight=100) - assert res.std() < mask.std() - assert res.dtype is not np.dtype('uint8') + assert res.dtype == np.float + assert res.std() * 255 < mask.std() + # test wrong number of dimensions a = np.random.random((8, 8, 8, 8)) try: