Merge pull request #278 from wuan/tv_denoise_fix

fixed data of tv_denoise result images to be in default range for floats
This commit is contained in:
Emmanuelle Gouillart
2012-09-02 14:14:38 -07:00
2 changed files with 24 additions and 27 deletions
+8 -17
View File
@@ -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
+16 -10
View File
@@ -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: