rm CondaPkg environment
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
from skimage import data, img_as_float
|
||||
from skimage._shared import testing
|
||||
from skimage._shared.testing import assert_allclose
|
||||
from skimage._shared.utils import _supported_float_type
|
||||
from skimage.color import rgb2gray
|
||||
from skimage.metrics import mean_squared_error, normalized_root_mse
|
||||
from skimage.morphology import binary_dilation, disk
|
||||
from skimage.restoration import inpaint
|
||||
|
||||
|
||||
@testing.parametrize('dtype', [np.float16, np.float32, np.float64])
|
||||
@testing.parametrize('split_into_regions', [False, True])
|
||||
def test_inpaint_biharmonic_2d(dtype, split_into_regions):
|
||||
img = np.tile(np.square(np.linspace(0, 1, 5, dtype=dtype)), (5, 1))
|
||||
mask = np.zeros_like(img)
|
||||
mask[2, 2:] = 1
|
||||
mask[1, 3:] = 1
|
||||
mask[0, 4:] = 1
|
||||
img[np.where(mask)] = 0
|
||||
out = inpaint.inpaint_biharmonic(img, mask,
|
||||
split_into_regions=split_into_regions)
|
||||
assert out.dtype == _supported_float_type(img)
|
||||
|
||||
ref = np.array(
|
||||
[[0., 0.0625, 0.25000000, 0.5625000, 0.73925058],
|
||||
[0., 0.0625, 0.25000000, 0.5478048, 0.76557821],
|
||||
[0., 0.0625, 0.25842878, 0.5623079, 0.85927796],
|
||||
[0., 0.0625, 0.25000000, 0.5625000, 1.00000000],
|
||||
[0., 0.0625, 0.25000000, 0.5625000, 1.00000000]]
|
||||
)
|
||||
rtol = 1e-7 if dtype == np.float64 else 1e-6
|
||||
assert_allclose(ref, out, rtol=rtol)
|
||||
|
||||
|
||||
@testing.parametrize('channel_axis', [0, 1, -1])
|
||||
def test_inpaint_biharmonic_2d_color(channel_axis):
|
||||
img = img_as_float(data.astronaut()[:64, :64])
|
||||
|
||||
mask = np.zeros(img.shape[:2], dtype=bool)
|
||||
mask[8:16, :16] = 1
|
||||
img_defect = img * ~mask[..., np.newaxis]
|
||||
mse_defect = mean_squared_error(img, img_defect)
|
||||
|
||||
img_defect = np.moveaxis(img_defect, -1, channel_axis)
|
||||
img_restored = inpaint.inpaint_biharmonic(img_defect, mask,
|
||||
channel_axis=channel_axis)
|
||||
img_restored = np.moveaxis(img_restored, channel_axis, -1)
|
||||
mse_restored = mean_squared_error(img, img_restored)
|
||||
|
||||
assert mse_restored < 0.01 * mse_defect
|
||||
|
||||
|
||||
@testing.parametrize('dtype', [np.float32, np.float64])
|
||||
def test_inpaint_biharmonic_2d_float_dtypes(dtype):
|
||||
img = np.tile(np.square(np.linspace(0, 1, 5)), (5, 1))
|
||||
mask = np.zeros_like(img)
|
||||
mask[2, 2:] = 1
|
||||
mask[1, 3:] = 1
|
||||
mask[0, 4:] = 1
|
||||
img[np.where(mask)] = 0
|
||||
img = img.astype(dtype, copy=False)
|
||||
out = inpaint.inpaint_biharmonic(img, mask)
|
||||
assert out.dtype == img.dtype
|
||||
ref = np.array(
|
||||
[[0., 0.0625, 0.25000000, 0.5625000, 0.73925058],
|
||||
[0., 0.0625, 0.25000000, 0.5478048, 0.76557821],
|
||||
[0., 0.0625, 0.25842878, 0.5623079, 0.85927796],
|
||||
[0., 0.0625, 0.25000000, 0.5625000, 1.00000000],
|
||||
[0., 0.0625, 0.25000000, 0.5625000, 1.00000000]]
|
||||
)
|
||||
assert_allclose(ref, out, rtol=1e-5)
|
||||
|
||||
|
||||
@testing.parametrize('split_into_regions', [False, True])
|
||||
def test_inpaint_biharmonic_3d(split_into_regions):
|
||||
img = np.tile(np.square(np.linspace(0, 1, 5)), (5, 1))
|
||||
img = np.dstack((img, img.T))
|
||||
mask = np.zeros_like(img)
|
||||
mask[2, 2:, :] = 1
|
||||
mask[1, 3:, :] = 1
|
||||
mask[0, 4:, :] = 1
|
||||
img[np.where(mask)] = 0
|
||||
out = inpaint.inpaint_biharmonic(img, mask,
|
||||
split_into_regions=split_into_regions)
|
||||
ref = np.dstack((
|
||||
np.array(
|
||||
[[0.0000, 0.0625, 0.25000000, 0.56250000, 0.53752796],
|
||||
[0.0000, 0.0625, 0.25000000, 0.44443780, 0.53762210],
|
||||
[0.0000, 0.0625, 0.23693666, 0.46621112, 0.68615592],
|
||||
[0.0000, 0.0625, 0.25000000, 0.56250000, 1.00000000],
|
||||
[0.0000, 0.0625, 0.25000000, 0.56250000, 1.00000000]]),
|
||||
np.array(
|
||||
[[0.0000, 0.0000, 0.00000000, 0.00000000, 0.19621902],
|
||||
[0.0625, 0.0625, 0.06250000, 0.17470756, 0.30140091],
|
||||
[0.2500, 0.2500, 0.27241289, 0.35155440, 0.43068654],
|
||||
[0.5625, 0.5625, 0.56250000, 0.56250000, 0.56250000],
|
||||
[1.0000, 1.0000, 1.00000000, 1.00000000, 1.00000000]])
|
||||
))
|
||||
assert_allclose(ref, out)
|
||||
|
||||
|
||||
def test_invalid_input():
|
||||
img, mask = np.zeros([]), np.zeros([])
|
||||
with testing.raises(ValueError):
|
||||
inpaint.inpaint_biharmonic(img, mask)
|
||||
|
||||
img, mask = np.zeros((2, 2)), np.zeros((4, 1))
|
||||
with testing.raises(ValueError):
|
||||
inpaint.inpaint_biharmonic(img, mask)
|
||||
|
||||
img = np.ma.array(np.zeros((2, 2)), mask=[[0, 0], [0, 0]])
|
||||
mask = np.zeros((2, 2))
|
||||
with testing.raises(TypeError):
|
||||
inpaint.inpaint_biharmonic(img, mask)
|
||||
|
||||
|
||||
@testing.parametrize('dtype', [np.uint8, np.float32, np.float64])
|
||||
@testing.parametrize('order', ['C', 'F'])
|
||||
@testing.parametrize('channel_axis', [None, -1])
|
||||
@testing.parametrize('split_into_regions', [False, True])
|
||||
def test_inpaint_nrmse(dtype, order, channel_axis, split_into_regions):
|
||||
image_orig = data.astronaut()[:, :200]
|
||||
float_dtype = np.float32 if dtype == np.float32 else np.float64
|
||||
image_orig = image_orig.astype(float_dtype, copy=False)
|
||||
|
||||
# Create mask with six block defect regions
|
||||
mask = np.zeros(image_orig.shape[:-1], dtype=bool)
|
||||
mask[20:50, 3:20] = 1
|
||||
mask[165:180, 90:155] = 1
|
||||
mask[40:60, 170:195] = 1
|
||||
mask[-60:-40, 170:195] = 1
|
||||
mask[-180:-165, 90:155] = 1
|
||||
mask[-50:-20, :20] = 1
|
||||
|
||||
# add a few long, narrow defects
|
||||
mask[200:205, -200:] = 1
|
||||
mask[150:255, 20:22] = 1
|
||||
mask[365:368, 60:130] = 1
|
||||
|
||||
# add randomly positioned small point-like defects
|
||||
rstate = np.random.default_rng(0)
|
||||
for radius in [0, 2, 4]:
|
||||
# larger defects are less common
|
||||
thresh = 3.25 + 0.25 * radius # larger defects less common
|
||||
tmp_mask = rstate.standard_normal(image_orig.shape[:-1]) > thresh
|
||||
if radius > 0:
|
||||
tmp_mask = binary_dilation(tmp_mask, disk(radius, dtype=bool))
|
||||
mask[tmp_mask] = 1
|
||||
|
||||
# Defect image over the same region in each color channel
|
||||
image_defect = image_orig.copy()
|
||||
for layer in range(image_defect.shape[-1]):
|
||||
image_defect[np.where(mask)] = 0
|
||||
|
||||
if channel_axis is None:
|
||||
image_orig = rgb2gray(image_orig)
|
||||
image_defect = rgb2gray(image_defect)
|
||||
|
||||
image_orig = image_orig.astype(dtype, copy=False)
|
||||
image_defect = image_defect.astype(dtype, copy=False)
|
||||
|
||||
image_defect = np.asarray(image_defect, order=order)
|
||||
image_result = inpaint.inpaint_biharmonic(
|
||||
image_defect, mask, channel_axis=channel_axis,
|
||||
split_into_regions=split_into_regions
|
||||
)
|
||||
assert image_result.dtype == float_dtype
|
||||
|
||||
nrmse_defect = normalized_root_mse(image_orig, image_defect)
|
||||
nrmse_result = normalized_root_mse(img_as_float(image_orig), image_result)
|
||||
assert nrmse_result < 0.2 * nrmse_defect
|
||||
@@ -1,87 +0,0 @@
|
||||
import functools
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from skimage._shared.testing import assert_
|
||||
from skimage._shared.utils import _supported_float_type
|
||||
from skimage.data import binary_blobs
|
||||
from skimage.data import camera, chelsea
|
||||
from skimage.metrics import mean_squared_error as mse
|
||||
from skimage.restoration import (calibrate_denoiser,
|
||||
denoise_wavelet)
|
||||
from skimage.restoration.j_invariant import _invariant_denoise
|
||||
from skimage.util import img_as_float, random_noise
|
||||
|
||||
test_img = img_as_float(camera())
|
||||
test_img_color = img_as_float(chelsea())
|
||||
test_img_3d = img_as_float(binary_blobs(64, n_dim=3)) / 2
|
||||
noisy_img = random_noise(test_img, mode='gaussian', var=0.01)
|
||||
noisy_img_color = random_noise(test_img_color, mode='gaussian', var=0.01)
|
||||
noisy_img_3d = random_noise(test_img_3d, mode='gaussian', var=0.1)
|
||||
|
||||
_denoise_wavelet = functools.partial(denoise_wavelet, rescale_sigma=True)
|
||||
|
||||
|
||||
def test_invariant_denoise():
|
||||
denoised_img = _invariant_denoise(noisy_img, _denoise_wavelet)
|
||||
|
||||
denoised_mse = mse(denoised_img, test_img)
|
||||
original_mse = mse(noisy_img, test_img)
|
||||
assert_(denoised_mse < original_mse)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
|
||||
def test_invariant_denoise_color(dtype):
|
||||
denoised_img_color = _invariant_denoise(
|
||||
noisy_img_color.astype(dtype), _denoise_wavelet,
|
||||
denoiser_kwargs=dict(channel_axis=-1))
|
||||
denoised_mse = mse(denoised_img_color, test_img_color)
|
||||
original_mse = mse(noisy_img_color, test_img_color)
|
||||
assert denoised_mse < original_mse
|
||||
assert denoised_img_color.dtype == _supported_float_type(dtype)
|
||||
|
||||
|
||||
def test_invariant_denoise_3d():
|
||||
denoised_img_3d = _invariant_denoise(noisy_img_3d, _denoise_wavelet)
|
||||
|
||||
denoised_mse = mse(denoised_img_3d, test_img_3d)
|
||||
original_mse = mse(noisy_img_3d, test_img_3d)
|
||||
assert_(denoised_mse < original_mse)
|
||||
|
||||
|
||||
def test_calibrate_denoiser_extra_output():
|
||||
parameter_ranges = {'sigma': np.linspace(0.1, 1, 5) / 2}
|
||||
_, (parameters_tested, losses) = calibrate_denoiser(
|
||||
noisy_img,
|
||||
_denoise_wavelet,
|
||||
denoise_parameters=parameter_ranges,
|
||||
extra_output=True
|
||||
)
|
||||
|
||||
all_denoised = [_invariant_denoise(noisy_img, _denoise_wavelet,
|
||||
denoiser_kwargs=denoiser_kwargs)
|
||||
for denoiser_kwargs in parameters_tested]
|
||||
|
||||
ground_truth_losses = [mse(img, test_img) for img in all_denoised]
|
||||
assert_(np.argmin(losses) == np.argmin(ground_truth_losses))
|
||||
|
||||
|
||||
def test_calibrate_denoiser():
|
||||
parameter_ranges = {'sigma': np.linspace(0.1, 1, 5) / 2}
|
||||
|
||||
denoiser = calibrate_denoiser(noisy_img, _denoise_wavelet,
|
||||
denoise_parameters=parameter_ranges)
|
||||
|
||||
denoised_mse = mse(denoiser(noisy_img), test_img)
|
||||
original_mse = mse(noisy_img, test_img)
|
||||
assert_(denoised_mse < original_mse)
|
||||
|
||||
|
||||
def test_input_image_not_modified():
|
||||
input_image = noisy_img.copy()
|
||||
|
||||
parameter_ranges = {'sigma': np.random.random(5) / 2}
|
||||
calibrate_denoiser(input_image, _denoise_wavelet,
|
||||
denoise_parameters=parameter_ranges)
|
||||
|
||||
assert_(np.all(noisy_img == input_image))
|
||||
@@ -1,177 +0,0 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
from scipy import ndimage as ndi
|
||||
from scipy.signal import convolve2d, convolve
|
||||
|
||||
from skimage import restoration, util
|
||||
from skimage._shared import filters
|
||||
from skimage._shared.testing import fetch
|
||||
from skimage._shared.utils import _supported_float_type
|
||||
from skimage.color import rgb2gray
|
||||
from skimage.data import astronaut, camera
|
||||
from skimage.restoration import uft
|
||||
|
||||
test_img = util.img_as_float(camera())
|
||||
|
||||
|
||||
def _get_rtol_atol(dtype):
|
||||
rtol = 1e-3
|
||||
atol = 0
|
||||
if dtype == np.float16:
|
||||
rtol = 1e-2
|
||||
atol = 1e-3
|
||||
elif dtype == np.float32:
|
||||
atol = 1e-5
|
||||
return rtol, atol
|
||||
|
||||
|
||||
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
|
||||
@pytest.mark.parametrize('ndim', [1, 2, 3])
|
||||
def test_wiener(dtype, ndim):
|
||||
"""
|
||||
currently only performs pixelwise comparison to
|
||||
precomputed result in 2d case.
|
||||
"""
|
||||
|
||||
psf = np.ones([5] * ndim, dtype=dtype) / 5 ** ndim
|
||||
np.random.seed(0)
|
||||
# for ndim == 2 use camera (to compare to presaved result)
|
||||
if ndim != 2:
|
||||
test_img = np.random.randint(0, 100, [50] * ndim)
|
||||
else:
|
||||
test_img = util.img_as_float(camera())
|
||||
|
||||
data = convolve(test_img, psf, 'same')
|
||||
data += 0.1 * data.std() * np.random.standard_normal(data.shape)
|
||||
data = data.astype(dtype, copy=False)
|
||||
deconvolved = restoration.wiener(data, psf, 0.05)
|
||||
assert deconvolved.dtype == _supported_float_type(dtype)
|
||||
|
||||
if ndim == 2:
|
||||
rtol, atol = _get_rtol_atol(dtype)
|
||||
path = fetch('restoration/tests/camera_wiener.npy')
|
||||
np.testing.assert_allclose(deconvolved, np.load(path),
|
||||
rtol=rtol, atol=atol)
|
||||
|
||||
_, laplacian = uft.laplacian(ndim, data.shape)
|
||||
otf = uft.ir2tf(psf, data.shape, is_real=False)
|
||||
assert otf.real.dtype == _supported_float_type(dtype)
|
||||
deconvolved = restoration.wiener(data, otf, 0.05,
|
||||
reg=laplacian,
|
||||
is_real=False)
|
||||
assert deconvolved.real.dtype == _supported_float_type(dtype)
|
||||
if ndim == 2:
|
||||
np.testing.assert_allclose(np.real(deconvolved),
|
||||
np.load(path),
|
||||
rtol=rtol, atol=atol)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
|
||||
def test_unsupervised_wiener(dtype):
|
||||
psf = np.ones((5, 5), dtype=dtype) / 25
|
||||
data = convolve2d(test_img, psf, 'same')
|
||||
seed = 16829302
|
||||
# keep old-style RandomState here for compatibility with previously stored
|
||||
# reference data in camera_unsup.npy and camera_unsup2.npy
|
||||
rng = np.random.RandomState(seed)
|
||||
data += 0.1 * data.std() * rng.standard_normal(data.shape)
|
||||
data = data.astype(dtype, copy=False)
|
||||
deconvolved, _ = restoration.unsupervised_wiener(data, psf,
|
||||
random_state=seed)
|
||||
float_type = _supported_float_type(dtype)
|
||||
assert deconvolved.dtype == float_type
|
||||
|
||||
rtol, atol = _get_rtol_atol(dtype)
|
||||
path = fetch('restoration/tests/camera_unsup.npy')
|
||||
np.testing.assert_allclose(deconvolved, np.load(path), rtol=rtol,
|
||||
atol=atol)
|
||||
|
||||
_, laplacian = uft.laplacian(2, data.shape)
|
||||
otf = uft.ir2tf(psf, data.shape, is_real=False)
|
||||
assert otf.real.dtype == _supported_float_type(dtype)
|
||||
deconvolved2 = restoration.unsupervised_wiener(
|
||||
data, otf, reg=laplacian, is_real=False,
|
||||
user_params={
|
||||
"callback": lambda x: None,
|
||||
"max_num_iter": 200,
|
||||
"min_num_iter": 30,
|
||||
},
|
||||
random_state=seed)[0]
|
||||
assert deconvolved2.real.dtype == float_type
|
||||
path = fetch('restoration/tests/camera_unsup2.npy')
|
||||
np.testing.assert_allclose(np.real(deconvolved2),
|
||||
np.load(path),
|
||||
rtol=rtol, atol=atol)
|
||||
|
||||
|
||||
def test_unsupervised_wiener_deprecated_user_param():
|
||||
psf = np.ones((5, 5), dtype=float) / 25
|
||||
data = convolve2d(test_img, psf, 'same')
|
||||
otf = uft.ir2tf(psf, data.shape, is_real=False)
|
||||
_, laplacian = uft.laplacian(2, data.shape)
|
||||
restoration.unsupervised_wiener(
|
||||
data, otf, reg=laplacian, is_real=False,
|
||||
user_params={"min_num_iter": 30}, random_state=5
|
||||
)
|
||||
|
||||
|
||||
def test_image_shape():
|
||||
"""Test that shape of output image in deconvolution is same as input.
|
||||
|
||||
This addresses issue #1172.
|
||||
"""
|
||||
point = np.zeros((5, 5), float)
|
||||
point[2, 2] = 1.
|
||||
psf = filters.gaussian(point, sigma=1., mode='reflect')
|
||||
# image shape: (45, 45), as reported in #1172
|
||||
image = util.img_as_float(camera()[65:165, 215:315]) # just the face
|
||||
image_conv = ndi.convolve(image, psf)
|
||||
deconv_sup = restoration.wiener(image_conv, psf, 1)
|
||||
deconv_un = restoration.unsupervised_wiener(image_conv, psf)[0]
|
||||
# test the shape
|
||||
np.testing.assert_equal(image.shape, deconv_sup.shape)
|
||||
np.testing.assert_equal(image.shape, deconv_un.shape)
|
||||
# test the reconstruction error
|
||||
sup_relative_error = np.abs(deconv_sup - image) / image
|
||||
un_relative_error = np.abs(deconv_un - image) / image
|
||||
np.testing.assert_array_less(np.median(sup_relative_error), 0.1)
|
||||
np.testing.assert_array_less(np.median(un_relative_error), 0.1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ndim', [1, 2, 3])
|
||||
def test_richardson_lucy(ndim):
|
||||
psf = np.ones([5] * ndim, dtype=float) / 5 ** ndim
|
||||
if ndim != 2:
|
||||
test_img = np.random.randint(0, 100, [30] * ndim)
|
||||
else:
|
||||
test_img = util.img_as_float(camera())
|
||||
data = convolve(test_img, psf, 'same')
|
||||
np.random.seed(0)
|
||||
data += 0.1 * data.std() * np.random.standard_normal(data.shape)
|
||||
deconvolved = restoration.richardson_lucy(data, psf, num_iter=5)
|
||||
|
||||
if ndim == 2:
|
||||
path = fetch('restoration/tests/camera_rl.npy')
|
||||
np.testing.assert_allclose(deconvolved, np.load(path), rtol=1e-3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('dtype_image', [np.float16, np.float32, np.float64])
|
||||
@pytest.mark.parametrize('dtype_psf', [np.float32, np.float64])
|
||||
def test_richardson_lucy_filtered(dtype_image, dtype_psf):
|
||||
if dtype_image == np.float64:
|
||||
atol = 1e-8
|
||||
else:
|
||||
atol = 1e-5
|
||||
test_img_astro = rgb2gray(astronaut())
|
||||
|
||||
psf = np.ones((5, 5), dtype=dtype_psf) / 25
|
||||
data = convolve2d(test_img_astro, psf, 'same')
|
||||
data = data.astype(dtype_image, copy=False)
|
||||
|
||||
deconvolved = restoration.richardson_lucy(data, psf, 5,
|
||||
filter_epsilon=1e-6)
|
||||
assert deconvolved.dtype == _supported_float_type(data.dtype)
|
||||
|
||||
path = fetch('restoration/tests/astronaut_rl.npy')
|
||||
np.testing.assert_allclose(deconvolved, np.load(path), rtol=1e-3,
|
||||
atol=atol)
|
||||
@@ -1,103 +0,0 @@
|
||||
"""
|
||||
Tests for Rolling Ball Filter
|
||||
(skimage.restoration.rolling_ball)
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from skimage import data
|
||||
from skimage.restoration import rolling_ball
|
||||
from skimage.restoration.rolling_ball import ellipsoid_kernel
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'dtype',
|
||||
[np.uint8, np.int32, np.float16, np.float32, np.float64]
|
||||
)
|
||||
def test_ellipsoid_const(dtype):
|
||||
img = 155 * np.ones((100, 100), dtype=dtype)
|
||||
kernel = ellipsoid_kernel((25, 53), 50)
|
||||
background = rolling_ball(img, kernel=kernel)
|
||||
assert np.allclose(img - background, np.zeros_like(img))
|
||||
assert background.dtype == img.dtype
|
||||
|
||||
|
||||
def test_nan_const():
|
||||
img = 123 * np.ones((100, 100), dtype=float)
|
||||
img[20, 20] = np.nan
|
||||
img[50, 53] = np.nan
|
||||
|
||||
kernel_shape = (10, 10)
|
||||
x = np.arange(-kernel_shape[1] // 2,
|
||||
kernel_shape[1] // 2 + 1)[np.newaxis, :]
|
||||
y = np.arange(-kernel_shape[0] // 2,
|
||||
kernel_shape[0] // 2 + 1)[:, np.newaxis]
|
||||
expected_img = np.zeros_like(img)
|
||||
expected_img[y + 20, x + 20] = np.nan
|
||||
expected_img[y + 50, x + 53] = np.nan
|
||||
kernel = ellipsoid_kernel(kernel_shape, 100)
|
||||
background = rolling_ball(
|
||||
img,
|
||||
kernel=kernel,
|
||||
nansafe=True
|
||||
)
|
||||
assert np.allclose(img - background, expected_img, equal_nan=True)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("radius", [1, 2.5, 10.346, 50])
|
||||
def test_const_image(radius):
|
||||
# infinite plane light source at top left corner
|
||||
img = 23 * np.ones((100, 100), dtype=np.uint8)
|
||||
background = rolling_ball(img, radius=radius)
|
||||
assert np.allclose(img - background, np.zeros_like(img))
|
||||
|
||||
|
||||
def test_radial_gradient():
|
||||
# spot light source at top left corner
|
||||
spot_radius = 50
|
||||
x, y = np.meshgrid(range(5), range(5))
|
||||
img = np.sqrt(np.clip(spot_radius ** 2 - y ** 2 - x ** 2, 0, None))
|
||||
|
||||
background = rolling_ball(img, radius=5)
|
||||
assert np.allclose(img - background, np.zeros_like(img))
|
||||
|
||||
|
||||
def test_linear_gradient():
|
||||
# linear light source centered at top left corner
|
||||
x, y = np.meshgrid(range(100), range(100))
|
||||
img = (y * 20 + x * 20)
|
||||
|
||||
expected_img = 19 * np.ones_like(img)
|
||||
expected_img[0, 0] = 0
|
||||
|
||||
background = rolling_ball(img, radius=1)
|
||||
assert np.allclose(img - background, expected_img)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("radius", [2, 10, 12.5, 50])
|
||||
def test_preserve_peaks(radius):
|
||||
x, y = np.meshgrid(range(100), range(100))
|
||||
img = 0 * x + 0 * y + 10
|
||||
img[10, 10] = 20
|
||||
img[20, 20] = 35
|
||||
img[45, 26] = 156
|
||||
|
||||
expected_img = img - 10
|
||||
background = rolling_ball(img, radius=radius)
|
||||
assert np.allclose(img - background, expected_img)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("num_threads", [None, 1, 2])
|
||||
def test_threads(num_threads):
|
||||
# not testing if we use multiple threads
|
||||
# just checking if the API throws an exception
|
||||
img = 23 * np.ones((100, 100), dtype=np.uint8)
|
||||
rolling_ball(img, radius=10, num_threads=num_threads)
|
||||
rolling_ball(img, radius=10, nansafe=True, num_threads=num_threads)
|
||||
|
||||
|
||||
def test_ndim():
|
||||
image = data.cells3d()[:5, 1, ...]
|
||||
kernel = ellipsoid_kernel((3, 100, 100), 100)
|
||||
rolling_ball(image, kernel=kernel)
|
||||
@@ -1,217 +0,0 @@
|
||||
import numpy as np
|
||||
from skimage.restoration import unwrap_phase
|
||||
import sys
|
||||
|
||||
from skimage._shared import testing
|
||||
from skimage._shared.testing import (assert_array_almost_equal_nulp,
|
||||
assert_almost_equal, assert_array_equal,
|
||||
assert_, skipif)
|
||||
from skimage._shared._warnings import expected_warnings
|
||||
|
||||
|
||||
def assert_phase_almost_equal(a, b, *args, **kwargs):
|
||||
"""An assert_almost_equal insensitive to phase shifts of n*2*pi."""
|
||||
shift = 2 * np.pi * np.round((b.mean() - a.mean()) / (2 * np.pi))
|
||||
with expected_warnings([r'invalid value encountered|\A\Z',
|
||||
r'divide by zero encountered|\A\Z']):
|
||||
print('assert_phase_allclose, abs', np.max(np.abs(a - (b - shift))))
|
||||
print('assert_phase_allclose, rel',
|
||||
np.max(np.abs((a - (b - shift)) / a)))
|
||||
if np.ma.isMaskedArray(a):
|
||||
assert_(np.ma.isMaskedArray(b))
|
||||
assert_array_equal(a.mask, b.mask)
|
||||
assert_(a.fill_value == b.fill_value)
|
||||
au = np.asarray(a)
|
||||
bu = np.asarray(b)
|
||||
with expected_warnings([r'invalid value encountered|\A\Z',
|
||||
r'divide by zero encountered|\A\Z']):
|
||||
print('assert_phase_allclose, no mask, abs',
|
||||
np.max(np.abs(au - (bu - shift))))
|
||||
print('assert_phase_allclose, no mask, rel',
|
||||
np.max(np.abs((au - (bu - shift)) / au)))
|
||||
assert_array_almost_equal_nulp(a + shift, b, *args, **kwargs)
|
||||
|
||||
|
||||
def check_unwrap(image, mask=None):
|
||||
image_wrapped = np.angle(np.exp(1j * image))
|
||||
if mask is not None:
|
||||
print('Testing a masked image')
|
||||
image = np.ma.array(image, mask=mask, fill_value=0.5)
|
||||
image_wrapped = np.ma.array(image_wrapped, mask=mask, fill_value=0.5)
|
||||
image_unwrapped = unwrap_phase(image_wrapped, seed=0)
|
||||
assert_phase_almost_equal(image_unwrapped, image)
|
||||
|
||||
|
||||
def test_unwrap_1d():
|
||||
image = np.linspace(0, 10 * np.pi, 100)
|
||||
check_unwrap(image)
|
||||
# Masked arrays are not allowed in 1D
|
||||
with testing.raises(ValueError):
|
||||
check_unwrap(image, True)
|
||||
# wrap_around is not allowed in 1D
|
||||
with testing.raises(ValueError):
|
||||
unwrap_phase(image, True, seed=0)
|
||||
|
||||
|
||||
@testing.parametrize("check_with_mask", (False, True))
|
||||
def test_unwrap_2d(check_with_mask):
|
||||
mask = None
|
||||
x, y = np.ogrid[:8, :16]
|
||||
image = 2 * np.pi * (x * 0.2 + y * 0.1)
|
||||
if check_with_mask:
|
||||
mask = np.zeros(image.shape, dtype=bool)
|
||||
mask[4:6, 4:8] = True
|
||||
check_unwrap(image, mask)
|
||||
|
||||
|
||||
@testing.parametrize("check_with_mask", (False, True))
|
||||
def test_unwrap_3d(check_with_mask):
|
||||
mask = None
|
||||
x, y, z = np.ogrid[:8, :12, :16]
|
||||
image = 2 * np.pi * (x * 0.2 + y * 0.1 + z * 0.05)
|
||||
if check_with_mask:
|
||||
mask = np.zeros(image.shape, dtype=bool)
|
||||
mask[4:6, 4:6, 1:3] = True
|
||||
check_unwrap(image, mask)
|
||||
|
||||
|
||||
def check_wrap_around(ndim, axis):
|
||||
# create a ramp, but with the last pixel along axis equalling the first
|
||||
elements = 100
|
||||
ramp = np.linspace(0, 12 * np.pi, elements)
|
||||
ramp[-1] = ramp[0]
|
||||
image = ramp.reshape(tuple([elements if n == axis else 1
|
||||
for n in range(ndim)]))
|
||||
image_wrapped = np.angle(np.exp(1j * image))
|
||||
|
||||
index_first = tuple([0] * ndim)
|
||||
index_last = tuple([-1 if n == axis else 0 for n in range(ndim)])
|
||||
# unwrap the image without wrap around
|
||||
# We do not want warnings about length 1 dimensions
|
||||
with expected_warnings([r'Image has a length 1 dimension|\A\Z']):
|
||||
image_unwrap_no_wrap_around = unwrap_phase(image_wrapped, seed=0)
|
||||
print('endpoints without wrap_around:',
|
||||
image_unwrap_no_wrap_around[index_first],
|
||||
image_unwrap_no_wrap_around[index_last])
|
||||
# without wrap around, the endpoints of the image should differ
|
||||
assert_(abs(image_unwrap_no_wrap_around[index_first] -
|
||||
image_unwrap_no_wrap_around[index_last]) > np.pi)
|
||||
# unwrap the image with wrap around
|
||||
wrap_around = [n == axis for n in range(ndim)]
|
||||
# We do not want warnings about length 1 dimensions
|
||||
with expected_warnings([r'Image has a length 1 dimension.|\A\Z']):
|
||||
image_unwrap_wrap_around = unwrap_phase(image_wrapped, wrap_around,
|
||||
seed=0)
|
||||
print('endpoints with wrap_around:',
|
||||
image_unwrap_wrap_around[index_first],
|
||||
image_unwrap_wrap_around[index_last])
|
||||
# with wrap around, the endpoints of the image should be equal
|
||||
assert_almost_equal(image_unwrap_wrap_around[index_first],
|
||||
image_unwrap_wrap_around[index_last])
|
||||
|
||||
|
||||
dim_axis = [(ndim, axis) for ndim in (2, 3) for axis in range(ndim)]
|
||||
|
||||
|
||||
@skipif(sys.version_info[:2] == (3, 4),
|
||||
reason="Doesn't work with python 3.4. See issue #3079")
|
||||
@testing.parametrize("ndim, axis", dim_axis)
|
||||
def test_wrap_around(ndim, axis):
|
||||
check_wrap_around(ndim, axis)
|
||||
|
||||
|
||||
def test_mask():
|
||||
length = 100
|
||||
ramps = [np.linspace(0, 4 * np.pi, length),
|
||||
np.linspace(0, 8 * np.pi, length),
|
||||
np.linspace(0, 6 * np.pi, length)]
|
||||
image = np.vstack(ramps)
|
||||
mask_1d = np.ones((length,), dtype=bool)
|
||||
mask_1d[0] = mask_1d[-1] = False
|
||||
for i in range(len(ramps)):
|
||||
# mask all ramps but the i'th one
|
||||
mask = np.zeros(image.shape, dtype=bool)
|
||||
mask |= mask_1d.reshape(1, -1)
|
||||
mask[i, :] = False # unmask i'th ramp
|
||||
image_wrapped = np.ma.array(np.angle(np.exp(1j * image)), mask=mask)
|
||||
image_unwrapped = unwrap_phase(image_wrapped)
|
||||
image_unwrapped -= image_unwrapped[0, 0] # remove phase shift
|
||||
# The end of the unwrapped array should have value equal to the
|
||||
# endpoint of the unmasked ramp
|
||||
assert_array_almost_equal_nulp(image_unwrapped[:, -1], image[i, -1])
|
||||
assert_(np.ma.isMaskedArray(image_unwrapped))
|
||||
|
||||
# Same tests, but forcing use of the 3D unwrapper by reshaping
|
||||
with expected_warnings(['length 1 dimension']):
|
||||
shape = (1,) + image_wrapped.shape
|
||||
image_wrapped_3d = image_wrapped.reshape(shape)
|
||||
image_unwrapped_3d = unwrap_phase(image_wrapped_3d)
|
||||
# remove phase shift
|
||||
image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0]
|
||||
assert_array_almost_equal_nulp(image_unwrapped_3d[:, :, -1],
|
||||
image[i, -1])
|
||||
|
||||
|
||||
def test_invalid_input():
|
||||
with testing.raises(ValueError):
|
||||
unwrap_phase(np.zeros([]))
|
||||
with testing.raises(ValueError):
|
||||
unwrap_phase(np.zeros((1, 1, 1, 1)))
|
||||
with testing.raises(ValueError):
|
||||
unwrap_phase(np.zeros((1, 1)), 3 * [False])
|
||||
with testing.raises(ValueError):
|
||||
unwrap_phase(np.zeros((1, 1)), 'False')
|
||||
|
||||
|
||||
def test_unwrap_3d_middle_wrap_around():
|
||||
# Segmentation fault in 3D unwrap phase with middle dimension connected
|
||||
# GitHub issue #1171
|
||||
image = np.zeros((20, 30, 40), dtype=np.float32)
|
||||
unwrap = unwrap_phase(image, wrap_around=[False, True, False])
|
||||
assert_(np.all(unwrap == 0))
|
||||
|
||||
|
||||
def test_unwrap_2d_compressed_mask():
|
||||
# ValueError when image is masked array with a compressed mask (no masked
|
||||
# elements). GitHub issue #1346
|
||||
image = np.ma.zeros((10, 10))
|
||||
unwrap = unwrap_phase(image)
|
||||
assert_(np.all(unwrap == 0))
|
||||
|
||||
|
||||
def test_unwrap_2d_all_masked():
|
||||
# Segmentation fault when image is masked array with a all elements masked
|
||||
# GitHub issue #1347
|
||||
# all elements masked
|
||||
image = np.ma.zeros((10, 10))
|
||||
image[:] = np.ma.masked
|
||||
unwrap = unwrap_phase(image)
|
||||
assert_(np.ma.isMaskedArray(unwrap))
|
||||
assert_(np.all(unwrap.mask))
|
||||
|
||||
# 1 unmasked element, still zero edges
|
||||
image = np.ma.zeros((10, 10))
|
||||
image[:] = np.ma.masked
|
||||
image[0, 0] = 0
|
||||
unwrap = unwrap_phase(image)
|
||||
assert_(np.ma.isMaskedArray(unwrap))
|
||||
assert_(np.sum(unwrap.mask) == 99) # all but one masked
|
||||
assert_(unwrap[0, 0] == 0)
|
||||
|
||||
|
||||
def test_unwrap_3d_all_masked():
|
||||
# all elements masked
|
||||
image = np.ma.zeros((10, 10, 10))
|
||||
image[:] = np.ma.masked
|
||||
unwrap = unwrap_phase(image)
|
||||
assert_(np.ma.isMaskedArray(unwrap))
|
||||
assert_(np.all(unwrap.mask))
|
||||
|
||||
# 1 unmasked element, still zero edges
|
||||
image = np.ma.zeros((10, 10, 10))
|
||||
image[:] = np.ma.masked
|
||||
image[0, 0, 0] = 0
|
||||
unwrap = unwrap_phase(image)
|
||||
assert_(np.ma.isMaskedArray(unwrap))
|
||||
assert_(np.sum(unwrap.mask) == 999) # all but one masked
|
||||
assert_(unwrap[0, 0, 0] == 0)
|
||||
Reference in New Issue
Block a user