Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
449
venv/Lib/site-packages/skimage/restoration/uft.py
Normal file
449
venv/Lib/site-packages/skimage/restoration/uft.py
Normal file
|
@ -0,0 +1,449 @@
|
|||
r"""Function of unitary fourier transform (uft) and utilities
|
||||
|
||||
This module implements the unitary fourier transform, also known as
|
||||
the ortho-normal transform. It is especially useful for convolution
|
||||
[1], as it respects the Parseval equality. The value of the null
|
||||
frequency is equal to
|
||||
|
||||
.. math:: \frac{1}{\sqrt{n}} \sum_i x_i
|
||||
|
||||
so the Fourier transform has the same energy as the original image
|
||||
(see ``image_quad_norm`` function). The transform is applied from the
|
||||
last axis for performance (assuming a C-order array input).
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] B. R. Hunt "A matrix theory proof of the discrete convolution
|
||||
theorem", IEEE Trans. on Audio and Electroacoustics,
|
||||
vol. au-19, no. 4, pp. 285-288, dec. 1971
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import numpy as np
|
||||
from .._shared.fft import fftmodule as fft
|
||||
|
||||
__keywords__ = "fft, Fourier Transform, orthonormal, unitary"
|
||||
|
||||
|
||||
def ufftn(inarray, dim=None):
|
||||
"""N-dimensional unitary Fourier transform.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
The array to transform.
|
||||
dim : int, optional
|
||||
The last axis along which to compute the transform. All
|
||||
axes by default.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray (same shape than inarray)
|
||||
The unitary N-D Fourier transform of ``inarray``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((3, 3, 3))
|
||||
>>> output = ufftn(input)
|
||||
>>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(3, 3, 3)
|
||||
"""
|
||||
if dim is None:
|
||||
dim = inarray.ndim
|
||||
outarray = fft.fftn(inarray, axes=range(-dim, 0), norm='ortho')
|
||||
return outarray
|
||||
|
||||
|
||||
def uifftn(inarray, dim=None):
|
||||
"""N-dimensional unitary inverse Fourier transform.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
The array to transform.
|
||||
dim : int, optional
|
||||
The last axis along which to compute the transform. All
|
||||
axes by default.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray (same shape than inarray)
|
||||
The unitary inverse N-D Fourier transform of ``inarray``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((3, 3, 3))
|
||||
>>> output = uifftn(input)
|
||||
>>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(3, 3, 3)
|
||||
"""
|
||||
if dim is None:
|
||||
dim = inarray.ndim
|
||||
outarray = fft.ifftn(inarray, axes=range(-dim, 0), norm='ortho')
|
||||
return outarray
|
||||
|
||||
|
||||
def urfftn(inarray, dim=None):
|
||||
"""N-dimensional real unitary Fourier transform.
|
||||
|
||||
This transform considers the Hermitian property of the transform on
|
||||
real-valued input.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray, shape (M, N, ..., P)
|
||||
The array to transform.
|
||||
dim : int, optional
|
||||
The last axis along which to compute the transform. All
|
||||
axes by default.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray, shape (M, N, ..., P / 2 + 1)
|
||||
The unitary N-D real Fourier transform of ``inarray``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The ``urfft`` functions assume an input array of real
|
||||
values. Consequently, the output has a Hermitian property and
|
||||
redundant values are not computed or returned.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((5, 5, 5))
|
||||
>>> output = urfftn(input)
|
||||
>>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(5, 5, 3)
|
||||
"""
|
||||
if dim is None:
|
||||
dim = inarray.ndim
|
||||
outarray = fft.rfftn(inarray, axes=range(-dim, 0), norm='ortho')
|
||||
return outarray
|
||||
|
||||
|
||||
def uirfftn(inarray, dim=None, shape=None):
|
||||
"""N-dimensional inverse real unitary Fourier transform.
|
||||
|
||||
This transform considers the Hermitian property of the transform
|
||||
from complex to real input.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
The array to transform.
|
||||
dim : int, optional
|
||||
The last axis along which to compute the transform. All
|
||||
axes by default.
|
||||
shape : tuple of int, optional
|
||||
The shape of the output. The shape of ``rfft`` is ambiguous in
|
||||
case of odd-valued input shape. In this case, this parameter
|
||||
should be provided. See ``np.fft.irfftn``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray
|
||||
The unitary N-D inverse real Fourier transform of ``inarray``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The ``uirfft`` function assumes that the output array is
|
||||
real-valued. Consequently, the input is assumed to have a Hermitian
|
||||
property and redundant values are implicit.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((5, 5, 5))
|
||||
>>> output = uirfftn(urfftn(input), shape=input.shape)
|
||||
>>> np.allclose(input, output)
|
||||
True
|
||||
>>> output.shape
|
||||
(5, 5, 5)
|
||||
"""
|
||||
if dim is None:
|
||||
dim = inarray.ndim
|
||||
outarray = fft.irfftn(inarray, shape, axes=range(-dim, 0), norm='ortho')
|
||||
return outarray
|
||||
|
||||
|
||||
def ufft2(inarray):
|
||||
"""2-dimensional unitary Fourier transform.
|
||||
|
||||
Compute the Fourier transform on the last 2 axes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
The array to transform.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray (same shape as inarray)
|
||||
The unitary 2-D Fourier transform of ``inarray``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
uifft2, ufftn, urfftn
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((10, 128, 128))
|
||||
>>> output = ufft2(input)
|
||||
>>> np.allclose(np.sum(input[1, ...]) / np.sqrt(input[1, ...].size),
|
||||
... output[1, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(10, 128, 128)
|
||||
"""
|
||||
return ufftn(inarray, 2)
|
||||
|
||||
|
||||
def uifft2(inarray):
|
||||
"""2-dimensional inverse unitary Fourier transform.
|
||||
|
||||
Compute the inverse Fourier transform on the last 2 axes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
The array to transform.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray (same shape as inarray)
|
||||
The unitary 2-D inverse Fourier transform of ``inarray``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
uifft2, uifftn, uirfftn
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((10, 128, 128))
|
||||
>>> output = uifft2(input)
|
||||
>>> np.allclose(np.sum(input[1, ...]) / np.sqrt(input[1, ...].size),
|
||||
... output[0, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(10, 128, 128)
|
||||
"""
|
||||
return uifftn(inarray, 2)
|
||||
|
||||
|
||||
def urfft2(inarray):
|
||||
"""2-dimensional real unitary Fourier transform
|
||||
|
||||
Compute the real Fourier transform on the last 2 axes. This
|
||||
transform considers the Hermitian property of the transform from
|
||||
complex to real-valued input.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray, shape (M, N, ..., P)
|
||||
The array to transform.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray, shape (M, N, ..., 2 * (P - 1))
|
||||
The unitary 2-D real Fourier transform of ``inarray``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
ufft2, ufftn, urfftn
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((10, 128, 128))
|
||||
>>> output = urfft2(input)
|
||||
>>> np.allclose(np.sum(input[1,...]) / np.sqrt(input[1,...].size),
|
||||
... output[1, 0, 0])
|
||||
True
|
||||
>>> output.shape
|
||||
(10, 128, 65)
|
||||
"""
|
||||
return urfftn(inarray, 2)
|
||||
|
||||
|
||||
def uirfft2(inarray, shape=None):
|
||||
"""2-dimensional inverse real unitary Fourier transform.
|
||||
|
||||
Compute the real inverse Fourier transform on the last 2 axes.
|
||||
This transform considers the Hermitian property of the transform
|
||||
from complex to real-valued input.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray, shape (M, N, ..., P)
|
||||
The array to transform.
|
||||
shape : tuple of int, optional
|
||||
The shape of the output. The shape of ``rfft`` is ambiguous in
|
||||
case of odd-valued input shape. In this case, this parameter
|
||||
should be provided. See ``np.fft.irfftn``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
outarray : ndarray, shape (M, N, ..., 2 * (P - 1))
|
||||
The unitary 2-D inverse real Fourier transform of ``inarray``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
urfft2, uifftn, uirfftn
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((10, 128, 128))
|
||||
>>> output = uirfftn(urfftn(input), shape=input.shape)
|
||||
>>> np.allclose(input, output)
|
||||
True
|
||||
>>> output.shape
|
||||
(10, 128, 128)
|
||||
"""
|
||||
return uirfftn(inarray, 2, shape=shape)
|
||||
|
||||
|
||||
def image_quad_norm(inarray):
|
||||
"""Return the quadratic norm of images in Fourier space.
|
||||
|
||||
This function detects whether the input image satisfies the
|
||||
Hermitian property.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
inarray : ndarray
|
||||
Input image. The image data should reside in the final two
|
||||
axes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
norm : float
|
||||
The quadratic norm of ``inarray``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> input = np.ones((5, 5))
|
||||
>>> image_quad_norm(ufft2(input)) == np.sum(np.abs(input)**2)
|
||||
True
|
||||
>>> image_quad_norm(ufft2(input)) == image_quad_norm(urfft2(input))
|
||||
True
|
||||
"""
|
||||
# If there is a Hermitian symmetry
|
||||
if inarray.shape[-1] != inarray.shape[-2]:
|
||||
return (2 * np.sum(np.sum(np.abs(inarray) ** 2, axis=-1), axis=-1) -
|
||||
np.sum(np.abs(inarray[..., 0]) ** 2, axis=-1))
|
||||
else:
|
||||
return np.sum(np.sum(np.abs(inarray) ** 2, axis=-1), axis=-1)
|
||||
|
||||
|
||||
def ir2tf(imp_resp, shape, dim=None, is_real=True):
|
||||
"""Compute the transfer function of an impulse response (IR).
|
||||
|
||||
This function makes the necessary correct zero-padding, zero
|
||||
convention, correct fft2, etc... to compute the transfer function
|
||||
of IR. To use with unitary Fourier transform for the signal (ufftn
|
||||
or equivalent).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
imp_resp : ndarray
|
||||
The impulse responses.
|
||||
shape : tuple of int
|
||||
A tuple of integer corresponding to the target shape of the
|
||||
transfer function.
|
||||
dim : int, optional
|
||||
The last axis along which to compute the transform. All
|
||||
axes by default.
|
||||
is_real : boolean, optional
|
||||
If True (default), imp_resp is supposed real and the Hermitian property
|
||||
is used with rfftn Fourier transform.
|
||||
|
||||
Returns
|
||||
-------
|
||||
y : complex ndarray
|
||||
The transfer function of shape ``shape``.
|
||||
|
||||
See Also
|
||||
--------
|
||||
ufftn, uifftn, urfftn, uirfftn
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> np.all(np.array([[4, 0], [0, 0]]) == ir2tf(np.ones((2, 2)), (2, 2)))
|
||||
True
|
||||
>>> ir2tf(np.ones((2, 2)), (512, 512)).shape == (512, 257)
|
||||
True
|
||||
>>> ir2tf(np.ones((2, 2)), (512, 512), is_real=False).shape == (512, 512)
|
||||
True
|
||||
|
||||
Notes
|
||||
-----
|
||||
The input array can be composed of multiple-dimensional IR with
|
||||
an arbitrary number of IR. The individual IR must be accessed
|
||||
through the first axes. The last ``dim`` axes contain the space
|
||||
definition.
|
||||
"""
|
||||
if not dim:
|
||||
dim = imp_resp.ndim
|
||||
# Zero padding and fill
|
||||
irpadded = np.zeros(shape)
|
||||
irpadded[tuple([slice(0, s) for s in imp_resp.shape])] = imp_resp
|
||||
# Roll for zero convention of the fft to avoid the phase
|
||||
# problem. Work with odd and even size.
|
||||
for axis, axis_size in enumerate(imp_resp.shape):
|
||||
if axis >= imp_resp.ndim - dim:
|
||||
irpadded = np.roll(irpadded,
|
||||
shift=-int(np.floor(axis_size / 2)),
|
||||
axis=axis)
|
||||
if is_real:
|
||||
return fft.rfftn(irpadded, axes=range(-dim, 0))
|
||||
else:
|
||||
return fft.fftn(irpadded, axes=range(-dim, 0))
|
||||
|
||||
|
||||
def laplacian(ndim, shape, is_real=True):
|
||||
"""Return the transfer function of the Laplacian.
|
||||
|
||||
Laplacian is the second order difference, on row and column.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ndim : int
|
||||
The dimension of the Laplacian.
|
||||
shape : tuple
|
||||
The support on which to compute the transfer function.
|
||||
is_real : boolean, optional
|
||||
If True (default), imp_resp is assumed to be real-valued and
|
||||
the Hermitian property is used with rfftn Fourier transform
|
||||
to return the transfer function.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tf : array_like, complex
|
||||
The transfer function.
|
||||
impr : array_like, real
|
||||
The Laplacian.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> tf, ir = laplacian(2, (32, 32))
|
||||
>>> np.all(ir == np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]]))
|
||||
True
|
||||
>>> np.all(tf == ir2tf(ir, (32, 32)))
|
||||
True
|
||||
"""
|
||||
impr = np.zeros([3] * ndim)
|
||||
for dim in range(ndim):
|
||||
idx = tuple([slice(1, 2)] * dim +
|
||||
[slice(None)] +
|
||||
[slice(1, 2)] * (ndim - dim - 1))
|
||||
impr[idx] = np.array([-1.0,
|
||||
0.0,
|
||||
-1.0]).reshape([-1 if i == dim else 1
|
||||
for i in range(ndim)])
|
||||
impr[(slice(1, 2), ) * ndim] = 2.0 * ndim
|
||||
return ir2tf(impr, shape, is_real=is_real), impr
|
Loading…
Add table
Add a link
Reference in a new issue