使用FFT进行2D场的3D阵列表示

时间:2018-03-09 15:46:36

标签: python numpy fft

我需要获得复杂场的傅里叶变换。我正在使用python。

我的输入是xy平面中电场的2D快照。

我目前有一个3D数组F [x] [y] [z]其中F [x] [y] [0]包含实数分量而F [x] [y] 1包含复数该领域的组成部分。

我目前的代码很简单,并且这样做:

result=np.fft.fftn(F)
result=np.fft.fftshift(result)

我有以下问题:

1)这是否正确计算了场的傅里叶变换,还是应该将场输入为二维矩阵,而每个元素都包含实部和虚部?

2)我仅使用实数输入了字段的复杂分量值(即,如果复数值是6i我输入6),这是正确的还是应该作为复数值输入(即输入为& #39; 6J'?)

3)因为这在技术上是2D输入字段,我应该使用np.fft.fft2吗?这样做意味着输出不在中间。

4)输出看起来不像我期望F的傅里叶变换看起来像,我不确定我做错了什么。

完整的示例代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

x, y = np.meshgrid(np.linspace(-1,1,100), np.linspace(-1,1,100))
d = np.sqrt(x*x+y*y)
sigma, mu = .35, 0.0
g1 = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )

F=np.empty(shape=(300,300,2),dtype=complex)
for x in range(0,300):
        for y in range(0,300):
            if y<50 or x<100 or y>249 or x>199:
                    F[x][y][0]=g1[0][0]
                    F[x][y][1]=0j
            elif y<150:
                    F[x][y][0]=g1[x-100][y-50]
                    F[x][y][1]=0j
            else:
                    F[x][y][0]=g1[x-100][y-150]
                    F[x][y][1]=0j

F_2D=np.empty(shape=(300,300))
for x in range(0,300):
    for y in range(0,300):
            F_2D[x][y]=np.absolute(F[x][y][0])+np.absolute(F[x][y][1])

plt.imshow(F_2D)
plt.show()

result=np.fft.fftn(F)
result=np.fft.fftshift(result)

result_2D=np.empty(shape=(300,300))
for x in range(0,300):
    for y in range(0,300):
            result_2D[x][y]=np.absolute(result[x][y][0])+np.absolute(result[x][y][1])

plt.imshow(result_2D)
plt.show()

绘制F给出: F

使用np.fft.fftn,最后显示的图像是: fftn

使用np.fft.fft2: fft2

这些看起来都不像我期望F的傅里叶变换看起来像。

2 个答案:

答案 0 :(得分:1)

我在这里添加了另一个答案,适用于添加的代码。

答案仍为np.fft.fft2()。这是一个例子。我稍微修改了代码。为了验证我们需要fft2我丢弃了一个blob,然后我们知道单个高斯blob应该转换为高斯blob(具有某个相位,在绘制绝对值时不会显示) 。我还降低了标准偏差,使频率响应稍微扩大。

代码:

import numpy as np
import matplotlib.pyplot as plt

x, y = np.meshgrid(np.linspace(-1,1,100), np.linspace(-1,1,100))
d = np.sqrt(x**2+y**2)
sigma, mu = .1, 0.0
g1 = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
N = 300
positions = [ [150,100] ]#, [150,200] ]
sz2 = [int(x/2) for x in g1.shape]
F_2D = np.zeros([N,N])
for x0,y0 in positions:
    F_2D[ x0-sz2[0]: x0+sz2[0], y0-sz2[1]:y0+sz2[1] ] = g1 + 1j*0.

result = np.fft.fftshift(np.fft.fft2(F_2D))

plt.subplot(211); plt.imshow(F_2D)
plt.subplot(212); plt.imshow(np.absolute(result))
plt.title('$\sigma$=.1')
plt.show()

结果:

Example result 1

要回到原来的问题,我们只需要改变

positions = [ [150,100] , [150,200] ]sigma=.35代替sigma=.1

答案 1 :(得分:0)

您应该使用复杂的numpy变量(使用1j)并使用fft2。例如:

N = 16
x0 = np.random.randn(N,N,2)
x = x0[:,:,0] + 1j*x0[:,:,1]
X = np.fft.fft2(x)

fftn上使用x0将执行3D FFT,使用fft将执行矢量1D FFT。