FFT 结果 Matlab VS Numpy (Python):结果不一样
FFT results Matlab VS Numpy (Python) : not the same results
我有一个 Matlab 脚本来计算信号的 DFT 并绘制它:
(数据可查here)
clc; clear; close all;
fid = fopen('s.txt');
txt = textscan(fid,'%f');
s = cell2mat(txt);
nFFT = 100;
fs = 24000;
deltaF = fs/nFFT;
FFFT = [0:nFFT/2-1]*deltaF;
win = hann(length(s));
sw = s.*win;
FFT = fft(sw, nFFT)/length(s);
FFT = [FFT(1); 2*FFT(2:nFFT/2)];
absFFT = 20*log10(abs(FFT));
plot(FFFT, absFFT)
grid on
我正在尝试将其翻译成 Python,但无法获得相同的结果。
import numpy as np
from matplotlib import pyplot as plt
x = np.genfromtxt("s.txt", delimiter=' ')
nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = [n * deltaF for n in range(nfft/2-1)]
ffft = np.array(ffft)
window = np.hanning(len(x))
xw = np.multiply(x, window)
fft = np.fft.fft(xw, nfft)/len(x)
fft = fft[0]+ [2*fft[1:nfft/2]]
fftabs = 20*np.log10(np.absolute(fft))
plt.figure()
plt.plot(ffft, np.transpose(fftabs))
plt.grid()
我得到的图(左边是Matlab,右边是Python):
我做错了什么?
我不是 Mathlab 用户,所以我不确定,但有几件事我想问一下,看看我是否可以帮助你。
您在创建数组后调用了 np.array (ffft)。这可能不会像您希望的那样改变数组的性质,也许最好尝试在 np.array(n * deltaF for n in range(nfft/2-1))
中定义它我不确定格式,但您明白了。另一件事是范围对我来说似乎不合适。您希望它的值为 49?
另一个是 fft = fft[0]+ [2*fft[1:nfft/2]]
与 FFT = [FFT(1); 2*FFT(2:nFFT/2)];
的比较 我不确定比较是否准确。对我来说,这似乎是一种不同类型的定义?
此外,当我进行这些类型的计算时,我 'print' 列出了中间步骤,这样我就可以比较数字以查看它在哪里中断。
希望对您有所帮助。
在您连接两个列表的一种情况下,两种代码都不同
FFT = [FFT(1); 2*FFT(2:nFFT/2)];
在matlab代码中
在另一个中,将 fft 的第一个值与向量的其余部分相加
fft = fft[0]+ [2*fft[1:nfft/2]]
'+' 不要在这里连接,因为你有 numpy 数组
在python中应该是:
fft = fft[0:nfft/2]
fft[1:nfft/2] = 2*fft[1:nfft/2]
我发现使用 np.fft.rfft
而不是 np.fft.fft
并按如下方式修改代码即可:
import numpy as np
from matplotlib import pyplot as pl
x = np.genfromtxt("../Matlab/s.txt", delimiter=' ')
nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = np.array([n * deltaF for n in range(nfft/2+1)])
window = np.hanning(len(x))
xw = np.multiply(x, window)
fft = np.fft.rfft(xw, nfft)/len(x)
fftabs = 20*np.log10(np.absolute(fft))
pl.figure()
pl.plot(np.transpose(ffft), fftabs)
pl.grid()
结果图:
right result with Python
我可以看到第一个点和最后一个点,以及振幅都不一样。这对我来说不是问题(我对一般形状更感兴趣),但如果有人能解释一下,我会很高兴。
我有一个 Matlab 脚本来计算信号的 DFT 并绘制它:
(数据可查here)
clc; clear; close all;
fid = fopen('s.txt');
txt = textscan(fid,'%f');
s = cell2mat(txt);
nFFT = 100;
fs = 24000;
deltaF = fs/nFFT;
FFFT = [0:nFFT/2-1]*deltaF;
win = hann(length(s));
sw = s.*win;
FFT = fft(sw, nFFT)/length(s);
FFT = [FFT(1); 2*FFT(2:nFFT/2)];
absFFT = 20*log10(abs(FFT));
plot(FFFT, absFFT)
grid on
我正在尝试将其翻译成 Python,但无法获得相同的结果。
import numpy as np
from matplotlib import pyplot as plt
x = np.genfromtxt("s.txt", delimiter=' ')
nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = [n * deltaF for n in range(nfft/2-1)]
ffft = np.array(ffft)
window = np.hanning(len(x))
xw = np.multiply(x, window)
fft = np.fft.fft(xw, nfft)/len(x)
fft = fft[0]+ [2*fft[1:nfft/2]]
fftabs = 20*np.log10(np.absolute(fft))
plt.figure()
plt.plot(ffft, np.transpose(fftabs))
plt.grid()
我得到的图(左边是Matlab,右边是Python):
我做错了什么?
我不是 Mathlab 用户,所以我不确定,但有几件事我想问一下,看看我是否可以帮助你。
您在创建数组后调用了 np.array (ffft)。这可能不会像您希望的那样改变数组的性质,也许最好尝试在 np.array(n * deltaF for n in range(nfft/2-1))
中定义它我不确定格式,但您明白了。另一件事是范围对我来说似乎不合适。您希望它的值为 49?
另一个是 fft = fft[0]+ [2*fft[1:nfft/2]]
与 FFT = [FFT(1); 2*FFT(2:nFFT/2)];
的比较 我不确定比较是否准确。对我来说,这似乎是一种不同类型的定义?
此外,当我进行这些类型的计算时,我 'print' 列出了中间步骤,这样我就可以比较数字以查看它在哪里中断。
希望对您有所帮助。
在您连接两个列表的一种情况下,两种代码都不同
FFT = [FFT(1); 2*FFT(2:nFFT/2)];
在matlab代码中
在另一个中,将 fft 的第一个值与向量的其余部分相加
fft = fft[0]+ [2*fft[1:nfft/2]]
'+' 不要在这里连接,因为你有 numpy 数组
在python中应该是:
fft = fft[0:nfft/2]
fft[1:nfft/2] = 2*fft[1:nfft/2]
我发现使用 np.fft.rfft
而不是 np.fft.fft
并按如下方式修改代码即可:
import numpy as np
from matplotlib import pyplot as pl
x = np.genfromtxt("../Matlab/s.txt", delimiter=' ')
nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = np.array([n * deltaF for n in range(nfft/2+1)])
window = np.hanning(len(x))
xw = np.multiply(x, window)
fft = np.fft.rfft(xw, nfft)/len(x)
fftabs = 20*np.log10(np.absolute(fft))
pl.figure()
pl.plot(np.transpose(ffft), fftabs)
pl.grid()
结果图: right result with Python
我可以看到第一个点和最后一个点,以及振幅都不一样。这对我来说不是问题(我对一般形状更感兴趣),但如果有人能解释一下,我会很高兴。