2017-06-21 224 views
0

我有一個MATLAB腳本來計算信號的DFT並繪製它:FFT結果Matlab的VS NumPy的(蟒蛇):不一樣的結果

(數據可以發現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

我在做什麼錯?

+0

也許不是你的主要問題,但你的窗口函數應該與FFT的大小相同,即nfft,而不是len(x)(適用於MATLAB和Python代碼)。 –

+0

@Paul R有趣,我在哪裏可以找到更多關於這方面的信息? – hibol

+0

StackOverflow涵蓋了窗口函數和FFT,其中有很多問題和答案。不過,最重要的一點是,您可以將[窗口函數](https://en.wikipedia.org/wiki/Window_function)應用於FFT的輸入數據,以減少[頻譜泄漏](https:// en。 wikipedia.org/wiki/Spectral_leakage)。因此這個窗口函數的大小需要與FFT的大小相匹配。 –

回答

3

兩個碼是在一種情況下不同您連接兩個列表

FFT = [FFT(1); 2*FFT(2:nFFT/2)]; 
在其他你用載體的其餘部分添加FFT的第一值的MATLAB代碼

fft = fft[0]+ [2*fft[1:nfft/2]] 

'+'在這裏沒有連接,因爲您有numpy數組

I ñ蟒蛇,它應該是:

fft = fft[0:nfft/2] 
fft[1:nfft/2] = 2*fft[1:nfft/2] 
0

我不是一個Mathlab用戶,所以我不確定,但是我會詢問是否可以幫助您。

在數組完成後(ffft),您調用np.array。這可能不會改變陣列的性質以及你所希望的,也許最好是嘗試在裏面定義它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)];相比我不確定比較是否準確。它對我來說似乎只是一種不同類型的定義?另外,當我進行這些類型的計算時,我會打印出中間步驟,以便比較數字以查看其中斷點。

希望這會有所幫助。

+0

謝謝。我改變了ffft的定義:'ffft = np.array(n * deltaF for n in range(nfft/2-1))'。不確定你提到的第二部分代碼。我找到了一個解決方案,並將其發佈在下面。而且我不關心我得到的積分數。我可能會用不同的值做一些測試。 – hibol

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

我可以看到第一個和最後一個點以及幅度不一樣。這對我來說不是問題(我對整體形狀更感興趣),但如果有人能解釋,我會很高興。