FFT结果Matlab VS Numpy(Python):结果不一样

时间:2017-06-21 13:04:46

标签: python matlab numpy fft

我有一个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 pl

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))

pl.figure()
pl.plot(ffft, np.transpose(fftabs))
pl.grid()

我得到的图(左边是Matlab,右边是Pyhton):

enter image description here

我做错了什么?

3 个答案:

答案 0 :(得分:3)

在连接两个列表

的情况下,两个代码都不同
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]

答案 1 :(得分:0)

我不是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)];相比我不确定比较是否准确。它对我来说似乎只是一种不同的定义?

另外,当我进行这些类型的计算时,我会打印'中间步骤,以便我可以比较数字,看看它在哪里。

希望这有帮助。

答案 2 :(得分:0)

我发现使用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

我可以看到第一个和最后一个点,以及振幅是不一样的。这对我来说不是问题(我对一般的形状更感兴趣),但如果有人可以解释,我会很开心。