2021-01-14 08:07:24 +01:00
|
|
|
import numpy as np
|
|
|
|
from skimage.data import camera
|
|
|
|
from skimage import restoration, data, io
|
|
|
|
import scipy.ndimage as ndi
|
|
|
|
|
|
|
|
|
|
|
|
class RestorationSuite:
|
|
|
|
"""Benchmark for restoration routines in scikit image."""
|
|
|
|
def setup(self):
|
|
|
|
nz = 32
|
|
|
|
self.volume_f64 = np.stack([camera()[::2, ::2], ] * nz,
|
|
|
|
axis=-1).astype(float) / 255
|
|
|
|
self.sigma = .05
|
|
|
|
self.volume_f64 += self.sigma * np.random.randn(*self.volume_f64.shape)
|
|
|
|
self.volume_f32 = self.volume_f64.astype(np.float32)
|
|
|
|
|
|
|
|
def peakmem_setup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def time_denoise_nl_means_f64(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f64, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=False,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
def time_denoise_nl_means_f32(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f32, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=False,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
def time_denoise_nl_means_fast_f64(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f64, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=True,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
def time_denoise_nl_means_fast_f32(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f32, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=True)
|
|
|
|
|
|
|
|
def peakmem_denoise_nl_means_f64(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f64, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=False,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
def peakmem_denoise_nl_means_f32(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f32, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=False)
|
|
|
|
|
|
|
|
def peakmem_denoise_nl_means_fast_f64(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f64, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=True,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
def peakmem_denoise_nl_means_fast_f32(self):
|
|
|
|
restoration.denoise_nl_means(self.volume_f32, patch_size=3,
|
|
|
|
patch_distance=2, sigma=self.sigma,
|
|
|
|
h=0.7 * self.sigma, fast_mode=True,
|
|
|
|
multichannel=False)
|
|
|
|
|
|
|
|
|
|
|
|
class DeconvolutionSuite:
|
|
|
|
"""Benchmark for restoration routines in scikit image."""
|
|
|
|
def setup(self):
|
|
|
|
nz = 32
|
|
|
|
self.volume_f64 = np.stack([camera()[::2, ::2], ] * nz,
|
|
|
|
axis=-1).astype(float) / 255
|
|
|
|
self.sigma = .02
|
|
|
|
self.psf_f64 = np.ones((5, 5, 5)) / 125
|
|
|
|
self.psf_f32 = self.psf_f64.astype(np.float32)
|
|
|
|
self.volume_f64 = ndi.convolve(self.volume_f64, self.psf_f64)
|
|
|
|
self.volume_f64 += self.sigma * np.random.randn(*self.volume_f64.shape)
|
|
|
|
self.volume_f32 = self.volume_f64.astype(np.float32)
|
|
|
|
|
|
|
|
def peakmem_setup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def time_richardson_lucy_f64(self):
|
|
|
|
restoration.richardson_lucy(self.volume_f64, self.psf_f64,
|
|
|
|
iterations=10)
|
|
|
|
|
|
|
|
def time_richardson_lucy_f32(self):
|
|
|
|
restoration.richardson_lucy(self.volume_f32, self.psf_f32,
|
|
|
|
iterations=10)
|
|
|
|
|
|
|
|
# use iterations=1 for peak-memory cases to save time
|
|
|
|
def peakmem_richardson_lucy_f64(self):
|
|
|
|
restoration.richardson_lucy(self.volume_f64, self.psf_f64,
|
|
|
|
iterations=1)
|
|
|
|
|
|
|
|
def peakmem_richardson_lucy_f32(self):
|
|
|
|
restoration.richardson_lucy(self.volume_f32, self.psf_f32,
|
|
|
|
iterations=1)
|
|
|
|
|
|
|
|
|
|
|
|
class RollingBall(object):
|
|
|
|
"""Benchmark Rolling Ball algorithm."""
|
|
|
|
|
|
|
|
timeout = 120
|
|
|
|
|
|
|
|
def time_rollingball(self, radius):
|
|
|
|
restoration.rolling_ball(data.coins(), radius=radius)
|
|
|
|
time_rollingball.params = [25, 50, 75, 100, 150, 200]
|
|
|
|
time_rollingball.param_names = ["radius"]
|
|
|
|
|
|
|
|
def peakmem_reference(self, *args):
|
|
|
|
"""Provide reference for memory measurement with empty benchmark.
|
|
|
|
|
|
|
|
Peakmem benchmarks measure the maximum amount of RAM used by a
|
|
|
|
function. However, this maximum also includes the memory used
|
|
|
|
during the setup routine (as of asv 0.2.1; see [1]_).
|
|
|
|
Measuring an empty peakmem function might allow us to disambiguate
|
|
|
|
between the memory used by setup and the memory used by target (see
|
|
|
|
other ``peakmem_`` functions below).
|
|
|
|
|
|
|
|
References
|
|
|
|
----------
|
|
|
|
.. [1]: https://asv.readthedocs.io/en/stable/writing_benchmarks.html#peak-memory
|
|
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
|
|
def peakmem_rollingball(self, radius):
|
|
|
|
restoration.rolling_ball(data.coins(), radius=radius)
|
|
|
|
peakmem_rollingball.params = [25, 50, 75, 100, 150, 200]
|
|
|
|
peakmem_rollingball.param_names = ["radius"]
|
|
|
|
|
|
|
|
def time_rollingball_nan(self, radius):
|
|
|
|
image = data.coins().astype(float)
|
|
|
|
pos = np.arange(np.min(image.shape))
|
|
|
|
image[pos, pos] = np.NaN
|
|
|
|
restoration.rolling_ball(image, radius=radius, nansafe=True)
|
|
|
|
time_rollingball_nan.params = [25, 50, 75, 100, 150, 200]
|
|
|
|
time_rollingball_nan.param_names = ["radius"]
|
|
|
|
|
|
|
|
def time_rollingball_ndim(self):
|
|
|
|
from skimage.restoration.rolling_ball import ellipsoid_kernel
|
|
|
|
image = data.cells3d()[:, 1, ...]
|
|
|
|
kernel = ellipsoid_kernel((1, 100, 100), 100)
|
|
|
|
restoration.rolling_ball(
|
|
|
|
image, kernel=kernel)
|
|
|
|
|
|
|
|
def time_rollingball_threads(self, threads):
|
|
|
|
restoration.rolling_ball(data.coins(), radius=100, num_threads=threads)
|
|
|
|
time_rollingball_threads.params = range(0, 9)
|
|
|
|
time_rollingball_threads.param_names = ["threads"]
|