web-dev-qa-db-ja.com

Scipy / Numpy FFT周波数分析

私は、fftの周波数軸(scipy.fftpack.fftfreqで取得)を、ビンまたは小数ビンではなく、ヘルツの周波数に変換する方法を探しています。

私はFFTをテストするために以下のコードを試しました:

t = scipy.linspace(0,120,4000)
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t))

signal = acc(t)

FFT = abs(scipy.fft(signal))
FFT = scipy.fftpack.fftshift(FFT)
freqs = scipy.fftpack.fftfreq(signal.size)

pylab.plot(freqs,FFT,'x')
pylab.show()

サンプリングレートは4000サンプル/ 120秒= 33.34サンプル/秒である必要があります。

信号には、2.0 Hz信号、8.0 Hz信号、およびランダムノイズがあります。

FFTを取得し、周波数を取得してプロットします。数字はまったく無意味です。周波数に33.34(サンプリング周波数)を掛けると、約8 Hzと15 Hzでピークが得られますが、これは間違っているようです(また、周波数は2ではなく4倍離れている必要があります!)。

ここで私が間違っていることについて何か考えはありますか?

32

私はあなたがfftshift()を行う必要はないと思うし、サンプリング期間をfftfreq()に渡すことができます:

import scipy
import scipy.fftpack
import pylab
from scipy import pi
t = scipy.linspace(0,120,4000)
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t))

signal = acc(t)

FFT = abs(scipy.fft(signal))
freqs = scipy.fftpack.fftfreq(signal.size, t[1]-t[0])

pylab.subplot(211)
pylab.plot(t, signal)
pylab.subplot(212)
pylab.plot(freqs,20*scipy.log10(FFT),'x')
pylab.show()

グラフから、2Hzと8Hzに2つのピークがあることがわかります。

enter image description here

48
HYRY

scipy.fftpack.fftfreq(n、d)は、周波数を直接提供します。 d=1/33.34を設定すると、fftの各ポイントの周波数がHz単位でわかります。

11
tom10

各ビンの周波数幅は(sampling_freq/num_bins)です。

より根本的な問題は、サンプルレートが目的の信号に対して十分でないことです。サンプルレートは8.3 Hzです。 8Hzの入力トーンをキャプチャするには、少なくとも16Hzが必要です。1


1.すべてのDSPエキスパートに。関連するのは実際にはBWであり、最大周波数ではないことを認識しています。しかし、私はOPがアンダーサンプリングされたデータ取得を行いたくないと考えています。

6