从 MATLAB 到 Python 的 2D FFT
2D FFT from MATLAB to Python
我的大部分编程经验都在 MATLAB 中,我最近开始熟悉 Python。
我遇到了一些很棒的 MATLAB 代码 ,它们与我想使用的一些东西有关,所以我尝试在 Python:
中重新创建它
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.linspace(-2, 2, 100) # seconds
y = np.linspace(-3, 3, 200) # seconds
xFreq = 2; # Hz
yFreq = -3; # Hz
a = np.matrix(np.matrix(np.exp(2j * np.pi * y * yFreq)))
b = np.matrix(np.exp(2j * np.pi * np.matrix(x).T * xFreq))
c = np.dot(b,a).T
plt.imshow(c.real, cmap='gray', extent = [min(x), max(x), min(y), max(y)], aspect=2/3);
plt.colorbar()
plt.xlabel('x (Sec)')
plt.ylabel('y (Sec)')
plt.show()
nfftx = len(x);
fs = 1/np.diff(x)[0];
fx = np.linspace(-1,1,nfftx) * fs/2;
nffty = len(y);
fs = 1/np.diff(y)[0];
fy = np.linspace(-1,1,nffty) * fs/2;
imF = np.fft.fftshift(np.fft.fft2(c))/np.size(c)
plt.figure()
plt.title("FFT (real)")
plt.imshow(np.real(imF), cmap='gray', extent = [min(fx), max(fx), min(fy), max(fy)], aspect=2/3)
plt.xlabel('fx (Hz)')
plt.ylabel('fy (Hz)')
- 知道为什么 y 频率显示为 3 Hz 而不是 -3 Hz
- 看不懂原解说者在MATLAB中用这两行是干什么的:
Nfft = 4 * 2 .^ nextpow2(size(im));
imF = fftshift(fft2(im, Nfft(1), Nfft(2))) / numel(im);
这可能就是我的 FFT 信号相对于背景如此强烈的原因。关于如何在 Python?
中调整 FFT 的想法
我只有部分答案。
如果你仔细观察,用你的 Python 代码生成的正弦图像和你链接的 Matlab 代码生成的正弦图像的颜色是反色的(检查靠近边缘的条纹的颜色,以及颜色条上的颜色)。
这就解释了为什么 FFT 图上的颜色倒置了,并且可能就是为什么得到 3 Hz 而不是 -3 Hz 的原因。不幸的是,我现在无法访问带有 Python 的计算机,因此无法验证这一点。我想这可能是开始进行故障排除的好方法。
编辑:
是的,你是对的。我完全错过了 Matlab 脚本中的 flipud
。我不认为你的 c
计算有误。最简单的检查方法是保存 Matlab 数据并将其导入 Python.
在 Matlab 中:
save('data.mat', 'im')
然后使用 scipy
:
将其导入 Python
im_matlab = scipy.io.loadmat('data.mat')['im']
np.all(np.isclose(im_matlab, im))
如果最后一行给你True
,那说明计算是正确的。
关于绘图,imshow
假设原点(numpy 数组的第 0 个索引)是左上角,这是图像的标准。您可以通过在 plt.imshow
.
中使用 origin='lower'
关键字来更改此设置
关于 fftshift
,我认为 this answer 一个不同的 Whosebug 问题是你所需要的。
我的大部分编程经验都在 MATLAB 中,我最近开始熟悉 Python。
我遇到了一些很棒的 MATLAB 代码
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.linspace(-2, 2, 100) # seconds
y = np.linspace(-3, 3, 200) # seconds
xFreq = 2; # Hz
yFreq = -3; # Hz
a = np.matrix(np.matrix(np.exp(2j * np.pi * y * yFreq)))
b = np.matrix(np.exp(2j * np.pi * np.matrix(x).T * xFreq))
c = np.dot(b,a).T
plt.imshow(c.real, cmap='gray', extent = [min(x), max(x), min(y), max(y)], aspect=2/3);
plt.colorbar()
plt.xlabel('x (Sec)')
plt.ylabel('y (Sec)')
plt.show()
nfftx = len(x);
fs = 1/np.diff(x)[0];
fx = np.linspace(-1,1,nfftx) * fs/2;
nffty = len(y);
fs = 1/np.diff(y)[0];
fy = np.linspace(-1,1,nffty) * fs/2;
imF = np.fft.fftshift(np.fft.fft2(c))/np.size(c)
plt.figure()
plt.title("FFT (real)")
plt.imshow(np.real(imF), cmap='gray', extent = [min(fx), max(fx), min(fy), max(fy)], aspect=2/3)
plt.xlabel('fx (Hz)')
plt.ylabel('fy (Hz)')
- 知道为什么 y 频率显示为 3 Hz 而不是 -3 Hz
- 看不懂原解说者在MATLAB中用这两行是干什么的:
Nfft = 4 * 2 .^ nextpow2(size(im));
imF = fftshift(fft2(im, Nfft(1), Nfft(2))) / numel(im);
这可能就是我的 FFT 信号相对于背景如此强烈的原因。关于如何在 Python?
中调整 FFT 的想法我只有部分答案。
如果你仔细观察,用你的 Python 代码生成的正弦图像和你链接的 Matlab 代码生成的正弦图像的颜色是反色的(检查靠近边缘的条纹的颜色,以及颜色条上的颜色)。
这就解释了为什么 FFT 图上的颜色倒置了,并且可能就是为什么得到 3 Hz 而不是 -3 Hz 的原因。不幸的是,我现在无法访问带有 Python 的计算机,因此无法验证这一点。我想这可能是开始进行故障排除的好方法。
编辑:
是的,你是对的。我完全错过了 Matlab 脚本中的 flipud
。我不认为你的 c
计算有误。最简单的检查方法是保存 Matlab 数据并将其导入 Python.
在 Matlab 中:
save('data.mat', 'im')
然后使用 scipy
:
im_matlab = scipy.io.loadmat('data.mat')['im']
np.all(np.isclose(im_matlab, im))
如果最后一行给你True
,那说明计算是正确的。
关于绘图,imshow
假设原点(numpy 数组的第 0 个索引)是左上角,这是图像的标准。您可以通过在 plt.imshow
.
origin='lower'
关键字来更改此设置
关于 fftshift
,我认为 this answer 一个不同的 Whosebug 问题是你所需要的。