scikit-image
276 строк · 8.2 Кб
1import inspect2
3import numpy as np4import scipy.ndimage as ndi5
6from skimage.data import camera7from skimage import restoration, data, color8from skimage.morphology import binary_dilation9
10try:11from skimage.morphology import disk12except ImportError:13from skimage.morphology import circle as disk14from . import _channel_kwarg, _skip_slow15
16# inspect signature to automatically handle API changes across versions
17if 'num_iter' in inspect.signature(restoration.richardson_lucy).parameters:18rl_iter_kwarg = dict(num_iter=10)19else:20rl_iter_kwarg = dict(iterations=10)21
22
23class RestorationSuite:24"""Benchmark for restoration routines in scikit image."""25
26timeout = 12027
28def setup(self):29nz = 3230self.volume_f64 = (31np.stack(32[33camera()[::2, ::2],34]35* nz,36axis=-1,37).astype(float)38/ 25539)40self.sigma = 0.0541self.volume_f64 += self.sigma * np.random.randn(*self.volume_f64.shape)42self.volume_f32 = self.volume_f64.astype(np.float32)43
44def peakmem_setup(self):45pass46
47def time_denoise_nl_means_f64(self):48restoration.denoise_nl_means(49self.volume_f64,50patch_size=3,51patch_distance=2,52sigma=self.sigma,53h=0.7 * self.sigma,54fast_mode=False,55**_channel_kwarg(False),56)57
58def time_denoise_nl_means_f32(self):59restoration.denoise_nl_means(60self.volume_f32,61patch_size=3,62patch_distance=2,63sigma=self.sigma,64h=0.7 * self.sigma,65fast_mode=False,66**_channel_kwarg(False),67)68
69def time_denoise_nl_means_fast_f64(self):70restoration.denoise_nl_means(71self.volume_f64,72patch_size=3,73patch_distance=2,74sigma=self.sigma,75h=0.7 * self.sigma,76fast_mode=True,77**_channel_kwarg(False),78)79
80def time_denoise_nl_means_fast_f32(self):81restoration.denoise_nl_means(82self.volume_f32,83patch_size=3,84patch_distance=2,85sigma=self.sigma,86h=0.7 * self.sigma,87fast_mode=True,88)89
90def peakmem_denoise_nl_means_f64(self):91restoration.denoise_nl_means(92self.volume_f64,93patch_size=3,94patch_distance=2,95sigma=self.sigma,96h=0.7 * self.sigma,97fast_mode=False,98**_channel_kwarg(False),99)100
101def peakmem_denoise_nl_means_f32(self):102restoration.denoise_nl_means(103self.volume_f32,104patch_size=3,105patch_distance=2,106sigma=self.sigma,107h=0.7 * self.sigma,108fast_mode=False,109)110
111def peakmem_denoise_nl_means_fast_f64(self):112restoration.denoise_nl_means(113self.volume_f64,114patch_size=3,115patch_distance=2,116sigma=self.sigma,117h=0.7 * self.sigma,118fast_mode=True,119**_channel_kwarg(False),120)121
122def peakmem_denoise_nl_means_fast_f32(self):123restoration.denoise_nl_means(124self.volume_f32,125patch_size=3,126patch_distance=2,127sigma=self.sigma,128h=0.7 * self.sigma,129fast_mode=True,130**_channel_kwarg(False),131)132
133
134class DeconvolutionSuite:135"""Benchmark for restoration routines in scikit image."""136
137def setup(self):138nz = 32139self.volume_f64 = (140np.stack(141[142camera()[::2, ::2],143]144* nz,145axis=-1,146).astype(float)147/ 255148)149self.sigma = 0.02150self.psf_f64 = np.ones((5, 5, 5)) / 125151self.psf_f32 = self.psf_f64.astype(np.float32)152self.volume_f64 = ndi.convolve(self.volume_f64, self.psf_f64)153self.volume_f64 += self.sigma * np.random.randn(*self.volume_f64.shape)154self.volume_f32 = self.volume_f64.astype(np.float32)155
156def peakmem_setup(self):157pass158
159def time_richardson_lucy_f64(self):160restoration.richardson_lucy(self.volume_f64, self.psf_f64, **rl_iter_kwarg)161
162def time_richardson_lucy_f32(self):163restoration.richardson_lucy(self.volume_f32, self.psf_f32, **rl_iter_kwarg)164
165# use iterations=1 for peak-memory cases to save time166def peakmem_richardson_lucy_f64(self):167restoration.richardson_lucy(self.volume_f64, self.psf_f64, **rl_iter_kwarg)168
169def peakmem_richardson_lucy_f32(self):170restoration.richardson_lucy(self.volume_f32, self.psf_f32, **rl_iter_kwarg)171
172
173class RollingBall:174"""Benchmark Rolling Ball algorithm."""175
176timeout = 120177
178def time_rollingball(self, radius):179restoration.rolling_ball(data.coins(), radius=radius)180
181time_rollingball.params = [25, 50, 100, 200]182time_rollingball.param_names = ["radius"]183
184def peakmem_reference(self, *args):185"""Provide reference for memory measurement with empty benchmark.186
187Peakmem benchmarks measure the maximum amount of RAM used by a
188function. However, this maximum also includes the memory used
189during the setup routine (as of asv 0.2.1; see [1]_).
190Measuring an empty peakmem function might allow us to disambiguate
191between the memory used by setup and the memory used by target (see
192other ``peakmem_`` functions below).
193
194References
195----------
196.. [1]: https://asv.readthedocs.io/en/stable/writing_benchmarks.html#peak-memory
197"""
198pass199
200def peakmem_rollingball(self, radius):201restoration.rolling_ball(data.coins(), radius=radius)202
203peakmem_rollingball.params = [25, 50, 100, 200]204peakmem_rollingball.param_names = ["radius"]205
206def time_rollingball_nan(self, radius):207image = data.coins().astype(float)208pos = np.arange(np.min(image.shape))209image[pos, pos] = np.nan210restoration.rolling_ball(image, radius=radius, nansafe=True)211
212time_rollingball_nan.params = [25, 50, 100, 200]213time_rollingball_nan.param_names = ["radius"]214
215def time_rollingball_ndim(self):216from skimage.restoration._rolling_ball import ellipsoid_kernel217
218image = data.cells3d()[:, 1, ...]219kernel = ellipsoid_kernel((1, 100, 100), 100)220restoration.rolling_ball(image, kernel=kernel)221
222time_rollingball_ndim.setup = _skip_slow223
224def time_rollingball_threads(self, threads):225restoration.rolling_ball(data.coins(), radius=100, num_threads=threads)226
227time_rollingball_threads.params = (0, 2, 4, 8)228time_rollingball_threads.param_names = ["threads"]229
230
231class Inpaint:232"""Benchmark inpainting algorithm."""233
234def setup(self):235image = data.astronaut()236
237# Create mask with six block defect regions238mask = np.zeros(image.shape[:-1], dtype=bool)239mask[20:60, :20] = 1240mask[160:180, 70:155] = 1241mask[30:60, 170:195] = 1242mask[-60:-30, 170:195] = 1243mask[-180:-160, 70:155] = 1244mask[-60:-20, :20] = 1245
246# add a few long, narrow defects247mask[200:205, -200:] = 1248mask[150:255, 20:23] = 1249mask[365:368, 60:130] = 1250
251# add randomly positioned small point-like defects252rstate = np.random.RandomState(0)253for radius in [0, 2, 4]:254# larger defects are less common255thresh = 2.75 + 0.25 * radius # larger defects are less common256tmp_mask = rstate.randn(*image.shape[:-1]) > thresh257if radius > 0:258tmp_mask = binary_dilation(tmp_mask, disk(radius, dtype=bool))259mask[tmp_mask] = 1260
261for layer in range(image.shape[-1]):262image[np.where(mask)] = 0263
264self.image_defect = image265self.image_defect_gray = color.rgb2gray(image)266self.mask = mask267
268def time_inpaint_rgb(self):269restoration.inpaint_biharmonic(270self.image_defect, self.mask, **_channel_kwarg(True)271)272
273def time_inpaint_grey(self):274restoration.inpaint_biharmonic(275self.image_defect_gray, self.mask, **_channel_kwarg(False)276)277