Reputation: 1496
I am trying to extend the fft code that works fine for 1D arrays in python for images. Actually i know the problem is in logic in extension. I don't know much about FFTs and i have to submit assignments for Image Processing. I will be thankful for any hints or solutions
Here is the code, Actually, I'm trying to create a module for FFT in python, and it already worked fine for 1D with helps from rosetta Code's site.
from cmath import exp, pi
from math import log, ceil
def fft(f):
N = len(f)
if N <= 1: return f
even = fft(f[0::2])
odd = fft(f[1::2])
return [even[k] + exp(-2j*pi*k/N)*odd[k] for k in xrange(N/2)] + \
[even[k] - exp(-2j*pi*k/N)*odd[k] for k in xrange(N/2)]
def pad(f):
n = len(f)
N = 2 ** int(ceil(log(n, 2)))
F = f + [0] * (N - n)
return F, n
def unpad(F, n):
return F[0 : n]
def pad2(f):
m, n = len(f), len(f[0])
M, N = 2 ** int(ceil(log(m, 2))), 2 ** int(ceil(log(n, 2)))
F = [ [0]*N for _ in xrange(M) ]
for i in range(0, m):
for j in range(0, n):
F[i][j] = f[i][j]
return F, m, n
def fft1D(f):
Fu, n = pad(f)
return fft(Fu), n
def fft2D(f):
F, m, n = pad2(f)
M, N = len(F), len(F[0])
Fuv = [ [0]*N for _ in xrange(M) ]
for i in range(0, M):
Fxv = fft(F[i])
for j in range(0, N):
Fuv[i][j] = (fft(Fxv))[j]
return Fuv, [m, n]
I called this module with tis code:
from FFT import *
f= [0, 2, 3, 4]
F = fft1D(f)
print f, F
X, s = fft2D([[1,2,1,1],[2,1,2,2],[0,1,1,0], [0,1,1,1]])
for i in range(0, len(X)):
print X[i]
It's output is :
[0, 2, 3, 4] ([(9+0j), (-3+2j), (-3+0j), (-3-2j)], 4)
[(4+0j), (4-2.4492935982947064e-16j), (4+0j), (8+2.4492935982947064e-16j)]
[(8+0j), (8+2.4492935982947064e-16j), (8+0j), (4-2.4492935982947064e-16j)]
[0j, -2.33486982377251e-16j, (4+0j), (4+2.33486982377251e-16j)]
[0j, (4+0j), (4+0j), (4+0j)]
The first one for 1d is fine as i verified result with Matlab's output but for 2nd one the Matlab's output is:
>> fft([1,2,1,1;2,1,2,2;0,1,1,0;0,1,1,1])
ans =
3.0000 5.0000 5.0000 4.0000
1.0000 - 2.0000i 1.0000 0 - 1.0000i 1.0000 - 1.0000i
-1.0000 1.0000 -1.0000 -2.0000
1.0000 + 2.0000i 1.0000 0 + 1.0000i 1.0000 + 1.0000i
The output is different ,which means i'm doing something wrong in the code's logic.Please help without bothering as i have not studied FFT formally till now so i'm not able to understand the mathematics copmpletely, maybe after i studied it, i may figure the problem out.
Upvotes: 1
Views: 3479
Reputation: 437
I agree with isedev that you should use numpy. It already has a great fft package that can do transforms in n-dimensions.
http://docs.scipy.org/doc/numpy/reference/routines.fft.html
http://docs.scipy.org/doc/numpy-1.4.x/reference/generated/numpy.fft.fft.html
Upvotes: 1
Reputation: 87376
Your code is a little hard to follow, but it looks like you are taking the FFT along the same direction both times. Look up the integral from of the FT, you will see that the x
and y
integrations are independent. That is (sorry, this notation is awful, '
indicates a function in Fourier space)
FT(f(x, y), x) -> f'(k, y)
FT(f'(k, y), y) -> f''(k, w)
So what you want to do is take the FFT of each row (than is do N 1D FFTs) and shove the results into a new array (which takes you from f(x, y) -> f'(k, y)
). Then take the FFT of each column of that result array (doing M 1D FFTs) and shove those results into another new array (which takes you from f'(k, y) -> f''(k, w)
.
Upvotes: 3