MAINT: first pass features (see below)

im —> img
adds paper DOI
adds denoise_wavelet __init__
fixes typo in optional_requriments
This commit is contained in:
Scott Sievert
2016-07-16 11:51:58 -05:00
parent 1c38da0fca
commit 643fe77840
3 changed files with 36 additions and 26 deletions
+1 -1
View File
@@ -4,4 +4,4 @@ SimpleITK; python_version != '3.4' and python_version != '3.5'
astropy astropy
tifffile tifffile
imageio imageio
PyWavelet PyWavelets
+2 -1
View File
@@ -21,7 +21,7 @@ References
from .deconvolution import wiener, unsupervised_wiener, richardson_lucy from .deconvolution import wiener, unsupervised_wiener, richardson_lucy
from .unwrap import unwrap_phase from .unwrap import unwrap_phase
from ._denoise import denoise_tv_chambolle, denoise_tv_bregman, \ from ._denoise import denoise_tv_chambolle, denoise_tv_bregman, \
denoise_bilateral denoise_bilateral, denoise_wavelet
from .non_local_means import denoise_nl_means from .non_local_means import denoise_nl_means
from .inpaint import inpaint_biharmonic from .inpaint import inpaint_biharmonic
from .._shared.utils import copy_func, deprecated from .._shared.utils import copy_func, deprecated
@@ -37,6 +37,7 @@ __all__ = ['wiener',
'denoise_tv_bregman', 'denoise_tv_bregman',
'denoise_tv_chambolle', 'denoise_tv_chambolle',
'denoise_bilateral', 'denoise_bilateral',
'denoise_wavelet',
'denoise_nl_means', 'denoise_nl_means',
'nl_means_denoising', 'nl_means_denoising',
'inpaint_biharmonic'] 'inpaint_biharmonic']
+33 -24
View File
@@ -334,11 +334,11 @@ def denoise_tv_chambolle(im, weight=0.1, eps=2.e-4, n_iter_max=200,
return out return out
def _wavelet_threshold(im, wavelet, threshold=None, sigma=None, mode='soft'): def _wavelet_threshold(img, wavelet, threshold=None, sigma=None, mode='soft'):
"""Performs wavelet denoising. """Performs wavelet denoising.
Parameters Parameters
---------- ----------
im : ndarray (2d or 3d) of ints, uints or floats img : ndarray (2d or 3d) of ints, uints or floats
Input data to be denoised. `im` can be of any numeric type, Input data to be denoised. `im` can be of any numeric type,
but it is cast into an ndarray of floats for the computation but it is cast into an ndarray of floats for the computation
of the denoised image. of the denoised image.
@@ -347,11 +347,12 @@ def _wavelet_threshold(im, wavelet, threshold=None, sigma=None, mode='soft'):
[pywt.wavelist]_ outputs. For example, this may be any of ``{db1, db2, [pywt.wavelist]_ outputs. For example, this may be any of ``{db1, db2,
db3, db4, haar}``. db3, db4, haar}``.
sigma : float, optional sigma : float, optional
The standard deviation of the noise. The noise is estimated when sigma is None (the default). The standard deviation of the noise. The noise is estimated when sigma
is None (the default).
threshold : float, optional threshold : float, optional
The thresholding value. All wavelet coefficients less than this value The thresholding value. All wavelet coefficients less than this value
are set to 0. The default value (None) uses the SureShrink method found in are set to 0. The default value (None) uses the SureShrink method found
[1]_ to remove noise. in [1]_ to remove noise.
mode : {'soft', 'hard'}, optional mode : {'soft', 'hard'}, optional
An optional argument to choose the type of denoising performed. It An optional argument to choose the type of denoising performed. It
noted that choosing soft thresholding given additive noise finds the noted that choosing soft thresholding given additive noise finds the
@@ -367,10 +368,11 @@ def _wavelet_threshold(im, wavelet, threshold=None, sigma=None, mode='soft'):
.. [1] Chang, S. Grace, Bin Yu, and Martin Vetterli. "Adaptive wavelet .. [1] Chang, S. Grace, Bin Yu, and Martin Vetterli. "Adaptive wavelet
thresholding for image denoising and compression." Image Processing, thresholding for image denoising and compression." Image Processing,
IEEE Transactions on 9.9 (2000): 1532-1546. IEEE Transactions on 9.9 (2000): 1532-1546.
DOI: 10.1109/83.862633
""" """
import pywt import pywt
coeffs = pywt.wavedecn(im, wavelet=wavelet) coeffs = pywt.wavedecn(img, wavelet=wavelet)
detail_coeffs = coeffs[-1]['d' * im.ndim] detail_coeffs = coeffs[-1]['d' * img.ndim]
if sigma is None: if sigma is None:
# Estimate the noise std.dev as discussed in PR #1837 # Estimate the noise std.dev as discussed in PR #1837
@@ -378,7 +380,7 @@ def _wavelet_threshold(im, wavelet, threshold=None, sigma=None, mode='soft'):
if threshold is None: if threshold is None:
# The BayesShrink threshold from [1]_ in docstring # The BayesShrink threshold from [1]_ in docstring
threshold = sigma**2 / np.sqrt(max(im.var() - sigma**2, 0)) threshold = sigma**2 / np.sqrt(max(img.var() - sigma**2, 0))
denoised_detail = [{key: pywt.threshold(level[key], value=threshold, denoised_detail = [{key: pywt.threshold(level[key], value=threshold,
mode=mode) for key in level} for level in coeffs[1:]] mode=mode) for key in level} for level in coeffs[1:]]
@@ -386,11 +388,11 @@ def _wavelet_threshold(im, wavelet, threshold=None, sigma=None, mode='soft'):
return pywt.waverecn([denoised_root, *denoised_detail], wavelet) return pywt.waverecn([denoised_root, *denoised_detail], wavelet)
def denoise_wavelet(im, sigma=None, wavelet='db1', mode='soft'): def denoise_wavelet(img, sigma=None, wavelet='db1', mode='soft'):
"""Performs wavelet denoising on an image. r"""Performs wavelet denoising on an image.
Parameters Parameters
---------- ----------
im : ndarray (greater than 2d) of ints, uints or floats img : ndarray (greater than 2d) of ints, uints or floats
Input data to be denoised. `im` can be of any numeric type, Input data to be denoised. `im` can be of any numeric type,
but it is cast into an ndarray of floats for the computation but it is cast into an ndarray of floats for the computation
of the denoised image. of the denoised image.
@@ -405,34 +407,41 @@ def denoise_wavelet(im, sigma=None, wavelet='db1', mode='soft'):
An optional argument to choose the type of denoising performed. It An optional argument to choose the type of denoising performed. It
noted that choosing soft thresholding given additive noise finds the noted that choosing soft thresholding given additive noise finds the
best approximation of the original image. best approximation of the original image.
Returns Returns
------- -------
out : ndarray out : ndarray
Denoised image. Denoised image.
Notes Notes
----- -----
As with the Fourier transform, there is an analogue to frequency in the As with the Fourier transform, there is an analogue to frequency in the
wavelet domain. Correspondingly, many pixel values of an image are 0 after wavelet domain. Correspondingly, many pixel values of an image are 0 after
taking the wavelet transform. taking the wavelet transform.
By wavelet denoising, we are enforcing that many of the wavelet coefficients
are 0 while keeping the error small. When we use soft thresholding, our By wavelet denoising, we are enforcing that many of the wavelet
estimate is coefficients are 0 while keeping the error small. When we use soft
thresholding, our estimate is
.. math:: \widehat{x} = \arg \min_x ||z - x||_2^2 + \lambda ||x||_1 .. math:: \widehat{x} = \arg \min_x ||z - x||_2^2 + \lambda ||x||_1
where :math:`z` is the input image wavelet coefficients and :math:`\lambda` where :math:`z` is the input image wavelet coefficients and :math:`\lambda`
is the threshold. is the threshold.
This function performs wavelet denoising on each color plane separately. The
output is clipped between 0 and 1. This function performs wavelet denoising on each color plane separately.
The output is clipped between 0 and 1.
References References
---------- ----------
.. [1] Chang, S. Grace, Bin Yu, and Martin Vetterli. "Adaptive wavelet .. [1] Chang, S. Grace, Bin Yu, and Martin Vetterli. "Adaptive wavelet
thresholding for image denoising and compression." Image Processing, thresholding for image denoising and compression." Image Processing,
IEEE Transactions on 9.9 (2000): 1532-1546. IEEE Transactions on 9.9 (2000): 1532-1546.
.. [pywt.wavelist] http://pywavelets.readthedocs.org/en/latest/ref/wavelets.html#wavelet-wavelist DOI: 10.1109/83.862633
Examples Examples
-------- --------
>>> from skimage import color, data >>> from skimage import color, data
>>> img = data.astronaut() * 1.0 / 255 >>> img = img_as_float(data.astronaut())
>>> img = color.rgb2gray(img) >>> img = color.rgb2gray(img)
>>> img += 0.5 * img.std() * np.random.randn(*img.shape) >>> img += 0.5 * img.std() * np.random.randn(*img.shape)
>>> img = np.clip(img, 0, 1) >>> img = np.clip(img, 0, 1)
@@ -441,17 +450,17 @@ def denoise_wavelet(im, sigma=None, wavelet='db1', mode='soft'):
>>> assert denoised_img.max() <= 1.0 >>> assert denoised_img.max() <= 1.0
""" """
if not im.dtype.kind == 'f': if not img.dtype.kind == 'f':
im = img_as_float(im) img = img_as_float(img)
if im.ndim == 2: if img.ndim == 2:
out = _wavelet_threshold(im, wavelet=wavelet, mode=mode, out = _wavelet_threshold(img, wavelet=wavelet, mode=mode,
sigma=sigma) sigma=sigma)
else: else:
out = np.dstack([_wavelet_threshold(im[..., c], wavelet=wavelet, out = np.dstack([_wavelet_threshold(img[..., c], wavelet=wavelet,
mode=mode, sigma=sigma) mode=mode, sigma=sigma)
for c in range(im.ndim)]) for c in range(img.ndim)])
# ensure valid image in 0, 1 is returned # ensure valid image in 0, 1 is returned
return np.clip(out, 0, 1) return np.clip(out, 0, 1)