135 lines
3.3 KiB
Python
135 lines
3.3 KiB
Python
"""
|
|
:author: Gary Ruben, 2009
|
|
:license: modified BSD
|
|
"""
|
|
|
|
__all__ = ["frt2", "ifrt2"]
|
|
|
|
import numpy as np
|
|
from numpy import roll, newaxis
|
|
|
|
|
|
def frt2(a):
|
|
"""Compute the 2-dimensional finite radon transform (FRT) for an n x n
|
|
integer array.
|
|
|
|
Parameters
|
|
----------
|
|
a : array_like
|
|
A 2-D square n x n integer array.
|
|
|
|
Returns
|
|
-------
|
|
FRT : 2-D ndarray
|
|
Finite Radon Transform array of (n+1) x n integer coefficients.
|
|
|
|
See Also
|
|
--------
|
|
ifrt2 : The two-dimensional inverse FRT.
|
|
|
|
Notes
|
|
-----
|
|
The FRT has a unique inverse if and only if n is prime. [FRT]
|
|
The idea for this algorithm is due to Vlad Negnevitski.
|
|
|
|
Examples
|
|
--------
|
|
|
|
Generate a test image:
|
|
Use a prime number for the array dimensions
|
|
|
|
>>> SIZE = 59
|
|
>>> img = np.tri(SIZE, dtype=np.int32)
|
|
|
|
Apply the Finite Radon Transform:
|
|
|
|
>>> f = frt2(img)
|
|
|
|
References
|
|
----------
|
|
.. [FRT] A. Kingston and I. Svalbe, "Projective transforms on periodic
|
|
discrete image arrays," in P. Hawkes (Ed), Advances in Imaging
|
|
and Electron Physics, 139 (2006)
|
|
|
|
"""
|
|
if a.ndim != 2 or a.shape[0] != a.shape[1]:
|
|
raise ValueError("Input must be a square, 2-D array")
|
|
|
|
ai = a.copy()
|
|
n = ai.shape[0]
|
|
f = np.empty((n + 1, n), np.uint32)
|
|
f[0] = ai.sum(axis=0)
|
|
for m in range(1, n):
|
|
# Roll the pth row of ai left by p places
|
|
for row in range(1, n):
|
|
ai[row] = roll(ai[row], -row)
|
|
f[m] = ai.sum(axis=0)
|
|
f[n] = ai.sum(axis=1)
|
|
return f
|
|
|
|
|
|
def ifrt2(a):
|
|
"""Compute the 2-dimensional inverse finite radon transform (iFRT) for
|
|
an (n+1) x n integer array.
|
|
|
|
Parameters
|
|
----------
|
|
a : array_like
|
|
A 2-D (n+1) row x n column integer array.
|
|
|
|
Returns
|
|
-------
|
|
iFRT : 2-D n x n ndarray
|
|
Inverse Finite Radon Transform array of n x n integer coefficients.
|
|
|
|
See Also
|
|
--------
|
|
frt2 : The two-dimensional FRT
|
|
|
|
Notes
|
|
-----
|
|
The FRT has a unique inverse if and only if n is prime.
|
|
See [1]_ for an overview.
|
|
The idea for this algorithm is due to Vlad Negnevitski.
|
|
|
|
Examples
|
|
--------
|
|
|
|
>>> SIZE = 59
|
|
>>> img = np.tri(SIZE, dtype=np.int32)
|
|
|
|
Apply the Finite Radon Transform:
|
|
|
|
>>> f = frt2(img)
|
|
|
|
Apply the Inverse Finite Radon Transform to recover the input
|
|
|
|
>>> fi = ifrt2(f)
|
|
|
|
Check that it's identical to the original
|
|
|
|
>>> assert len(np.nonzero(img-fi)[0]) == 0
|
|
|
|
References
|
|
----------
|
|
.. [1] A. Kingston and I. Svalbe, "Projective transforms on periodic
|
|
discrete image arrays," in P. Hawkes (Ed), Advances in Imaging
|
|
and Electron Physics, 139 (2006)
|
|
|
|
"""
|
|
if a.ndim != 2 or a.shape[0] != a.shape[1] + 1:
|
|
raise ValueError("Input must be an (n+1) row x n column, 2-D array")
|
|
|
|
ai = a.copy()[:-1]
|
|
n = ai.shape[1]
|
|
f = np.empty((n, n), np.uint32)
|
|
f[0] = ai.sum(axis=0)
|
|
for m in range(1, n):
|
|
# Rolls the pth row of ai right by p places.
|
|
for row in range(1, ai.shape[0]):
|
|
ai[row] = roll(ai[row], row)
|
|
f[m] = ai.sum(axis=0)
|
|
f += a[-1][newaxis].T
|
|
f = (f - ai[0].sum()) / n
|
|
return f
|