CofeehousePy/deps/scikit-image/skimage/filters/_window.py

130 lines
4.4 KiB
Python

import functools
import numpy as np
from ..transform import warp
from .._shared.utils import safe_as_int
from scipy.signal import get_window
def window(window_type, shape, warp_kwargs=None):
"""Return an n-dimensional window of a given size and dimensionality.
Parameters
----------
window_type : string, float, or tuple
The type of window to be created. Any window type supported by
``scipy.signal.get_window`` is allowed here. See notes below for a
current list, or the SciPy documentation for the version of SciPy
on your machine.
shape : tuple of int or int
The shape of the window along each axis. If an integer is provided,
a 1D window is generated.
warp_kwargs : dict
Keyword arguments passed to `skimage.transform.warp` (e.g.,
``warp_kwargs={'order':3}`` to change interpolation method).
Returns
-------
nd_window : ndarray
A window of the specified ``shape``. ``dtype`` is ``np.double``.
Notes
-----
This function is based on ``scipy.signal.get_window`` and thus can access
all of the window types available to that function
(e.g., ``"hann"``, ``"boxcar"``). Note that certain window types require
parameters that have to be supplied with the window name as a tuple
(e.g., ``("tukey", 0.8)``). If only a float is supplied, it is interpreted
as the beta parameter of the Kaiser window.
See https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.windows.get_window.html
for more details.
Note that this function generates a double precision array of the specified
``shape`` and can thus generate very large arrays that consume a large
amount of available memory.
The approach taken here to create nD windows is to first calculate the
Euclidean distance from the center of the intended nD window to each
position in the array. That distance is used to sample, with
interpolation, from a 1D window returned from ``scipy.signal.get_window``.
The method of interpolation can be changed with the ``order`` keyword
argument passed to `skimage.transform.warp`.
Some coordinates in the output window will be outside of the original
signal; these will be filled in with zeros.
Window types:
- boxcar
- triang
- blackman
- hamming
- hann
- bartlett
- flattop
- parzen
- bohman
- blackmanharris
- nuttall
- barthann
- kaiser (needs beta)
- gaussian (needs standard deviation)
- general_gaussian (needs power, width)
- slepian (needs width)
- dpss (needs normalized half-bandwidth)
- chebwin (needs attenuation)
- exponential (needs decay scale)
- tukey (needs taper fraction)
Examples
--------
Return a Hann window with shape (512, 512):
>>> from skimage.filters import window
>>> w = window('hann', (512, 512))
Return a Kaiser window with beta parameter of 16 and shape (256, 256, 35):
>>> w = window(16, (256, 256, 35))
Return a Tukey window with an alpha parameter of 0.8 and shape (100, 300):
>>> w = window(('tukey', 0.8), (100, 300))
References
----------
.. [1] Two-dimensional window design, Wikipedia,
https://en.wikipedia.org/wiki/Two_dimensional_window_design
"""
if np.isscalar(shape):
shape = safe_as_int(shape),
else:
shape = tuple(safe_as_int(shape))
if any(s < 0 for s in shape):
raise ValueError("invalid shape")
ndim = len(shape)
if ndim <= 0:
raise ValueError("Number of dimensions must be greater than zero")
max_size = functools.reduce(max, shape)
w = get_window(window_type, max_size, fftbins=False)
w = np.reshape(w, (-1,) + (1,) * (ndim-1))
# Create coords for warping following `ndimage.map_coordinates` convention.
L = [np.arange(s, dtype=np.float32) * (max_size / s) for s in shape]
center = (max_size / 2) - 0.5
dist = 0
for g in np.meshgrid(*L, sparse=True, indexing='ij'):
g -= center
dist = dist + g * g
dist = np.sqrt(dist)
coords = np.zeros((ndim,) + dist.shape, dtype=np.float32)
coords[0] = dist + center
if warp_kwargs is None:
warp_kwargs = {}
return warp(w, coords, mode='constant', cval=0., **warp_kwargs)