diff --git a/TODO.txt b/TODO.txt index a6dc649e..9e31032b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -16,6 +16,8 @@ Version 0.14 * Remove deprecated ``skimage.data.lena`` and corresponding data files. * Remove deprecated ``skimage.measure.structural_similarity`` alias and deprecation warning test for this alias. +* Remove deprecated ``sigma_range`` kwargs in ``skimage.restoration.denoise_bilateral`` + and corresponding tests. Version 0.13 diff --git a/skimage/restoration/_denoise.py b/skimage/restoration/_denoise.py index 7d47225a..30954c70 100644 --- a/skimage/restoration/_denoise.py +++ b/skimage/restoration/_denoise.py @@ -1,13 +1,14 @@ # coding: utf-8 import numpy as np +from math import ceil from .. import img_as_float from ..restoration._denoise_cy import _denoise_bilateral, _denoise_tv_bregman -from .._shared.utils import _mode_deprecations +from .._shared.utils import _mode_deprecations, skimage_deprecation, warn import warnings -def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1, - bins=10000, mode='constant', cval=0, multichannel=True): +def denoise_bilateral(image, win_size=None, sigma_color=None, sigma_spatial=1, + bins=10000, mode='constant', cval=0, multichannel=True, sigma_range=None): """Denoise image using bilateral filter. This is an edge-preserving and noise reducing denoising filter. It averages @@ -19,7 +20,7 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1, Radiometric similarity is measured by the gaussian function of the euclidian distance between two color values and a certain standard deviation - (`sigma_range`). + (`sigma_color`). Parameters ---------- @@ -27,7 +28,8 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1, Input image, 2D grayscale or RGB. win_size : int Window size for filtering. - sigma_range : float + If win_size is not specified, it is calculated as max(5, 2*ceil(3*sigma_spatial)+1) + sigma_color : float Standard deviation for grayvalue/color distance (radiometric similarity). A larger value results in averaging of pixels with larger radiometric differences. Note, that the image will be converted using @@ -66,7 +68,7 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1, >>> astro = astro[220:300, 220:320] >>> noisy = astro + 0.6 * astro.std() * np.random.random(astro.shape) >>> noisy = np.clip(noisy, 0, 1) - >>> denoised = denoise_bilateral(noisy, sigma_range=0.05, sigma_spatial=15) + >>> denoised = denoise_bilateral(noisy, sigma_color=0.05, sigma_spatial=15) """ if multichannel: if image.ndim != 3: @@ -99,9 +101,19 @@ def denoise_bilateral(image, win_size=5, sigma_range=None, sigma_spatial=1, "``multichannel=True`` for 2-D RGB " "images.".format(image.shape)) + if sigma_range is not None: + warn('`sigma_range` has been deprecated in favor of ' + '`sigma_color`. The `sigma_range` keyword argument ' + 'will be removed in v0.14', skimage_deprecation) + + #If sigma_range is provided, assign it to sigma_color + sigma_color = sigma_range + + if win_size is None: + win_size = max(5, 2*int(ceil(3*sigma_spatial))+1) mode = _mode_deprecations(mode) - return _denoise_bilateral(image, win_size, sigma_range, sigma_spatial, + return _denoise_bilateral(image, win_size, sigma_color, sigma_spatial, bins, mode, cval) diff --git a/skimage/restoration/tests/test_denoise.py b/skimage/restoration/tests/test_denoise.py index e565d741..71adee3f 100644 --- a/skimage/restoration/tests/test_denoise.py +++ b/skimage/restoration/tests/test_denoise.py @@ -4,7 +4,6 @@ from numpy.testing import run_module_suite, assert_raises, assert_equal from skimage import restoration, data, color, img_as_float, measure from skimage._shared._warnings import expected_warnings - np.random.seed(1234) @@ -159,9 +158,9 @@ def test_denoise_bilateral_2d(): img += 0.5 * img.std() * np.random.rand(*img.shape) img = np.clip(img, 0, 1) - out1 = restoration.denoise_bilateral(img, sigma_range=0.1, + out1 = restoration.denoise_bilateral(img, sigma_color=0.1, sigma_spatial=20, multichannel=False) - out2 = restoration.denoise_bilateral(img, sigma_range=0.2, + out2 = restoration.denoise_bilateral(img, sigma_color=0.2, sigma_spatial=30, multichannel=False) # make sure noise is reduced in the checkerboard cells @@ -175,8 +174,8 @@ def test_denoise_bilateral_color(): img += 0.5 * img.std() * np.random.rand(*img.shape) img = np.clip(img, 0, 1) - out1 = restoration.denoise_bilateral(img, sigma_range=0.1, sigma_spatial=20) - out2 = restoration.denoise_bilateral(img, sigma_range=0.2, sigma_spatial=30) + out1 = restoration.denoise_bilateral(img, sigma_color=0.1, sigma_spatial=20) + out2 = restoration.denoise_bilateral(img, sigma_color=0.2, sigma_spatial=30) # make sure noise is reduced in the checkerboard cells assert img[30:45, 5:15].std() > out1[30:45, 5:15].std() @@ -212,6 +211,31 @@ def test_denoise_bilateral_nan(): out = restoration.denoise_bilateral(img, multichannel=False) assert_equal(img, out) +def test_denoise_sigma_range(): + img = checkerboard_gray.copy() + # add some random noise + img += 0.5 * img.std() * np.random.rand(*img.shape) + img = np.clip(img, 0, 1) + out1 = restoration.denoise_bilateral(img, sigma_color=0.1, + sigma_spatial=20, multichannel=False) + with expected_warnings('`sigma_range` has been deprecated in favor of `sigma_color`. ' + 'The `sigma_range` keyword argument will be removed in v0.14'): + out2 = restoration.denoise_bilateral(img, sigma_range=0.1, + sigma_spatial=20, multichannel=False) + assert_equal(out1, out2) + +def test_denoise_sigma_range_and_sigma_color(): + img = checkerboard_gray.copy() + # add some random noise + img += 0.5 * img.std() * np.random.rand(*img.shape) + img = np.clip(img, 0, 1) + out1 = restoration.denoise_bilateral(img, sigma_color=0.1, + sigma_spatial=20, multichannel=False) + with expected_warnings('`sigma_range` has been deprecated in favor of `sigma_color`. ' + 'The `sigma_range` keyword argument will be removed in v0.14'): + out2 = restoration.denoise_bilateral(img, sigma_color=0.2, sigma_range=0.1, + sigma_spatial=20, multichannel=False) + assert_equal(out1, out2) def test_nl_means_denoising_2d(): img = np.zeros((40, 40))