我們知道傅利葉變換能夠將時域的訊號變換到頻域分析,但是我們在計算機應用時,常常是離散的訊號。如,用adc採集回來的模擬訊號,就變成了離散的訊號。這時我們要對訊號進行分析,就不能再使用傅利葉變換了,而要使用離散傅利葉變換,dft:
x [k
]=∑n
=0n−
1x[n
]e−j
2π∗k
n/nx[k]=\sum_^x[n]e^
x[k]=∑
n=0n
−1x
[n]e
−j2π
∗kn/
n其中:
x [k
]x[k]
x[k]
:離散頻率下標為k時的頻率大小
x [n
]x[n]
x[n]
: 離散時域訊號序列
n
nn: 訊號序列的長度,也就是取樣的個數
下面我們用python來實現dft:
對於訊號y=s
in(2
∗π∗f
0∗t)
y = sin(2*\pi*f_0*t)
y=sin(
2∗π∗
f0∗
t)來進行dft。
f
0f_0
f0 設為10hz
取樣頻率f
sf_s
fs設為50hz
取樣個數n 設為100
所以y [n
]=x[
n]=s
in(2
∗π∗f
0∗n/
fs)y[n] =x[n]= sin(2*\pi*f_0*n/f_s)
y[n]=x
[n]=
sin(
2∗π∗
f0∗
n/fs
)n =0
…n−1
n=0…n-1
n=0…n−
1 x [k
]=si
n(2∗
π∗f0
∗n/f
s)e−
j2π∗
kn/n
x[k] = sin(2*\pi*f_0*n/f_s)e^
x[k]=s
in(2
∗π∗f
0∗n
/fs
)e−j
2π∗k
n/nk=1
…n−1
k=1…n-1
k=1…n−
1code:
from numpy import arange, sin, pi, cos
import matplotlib.pyplot as plt
import cmath
from scipy.fftpack import fft,ifft
kl = arange(0, 100, 1)
xk =
f0 = 10
fs = 50
n = len(kl)
y = sin(2*pi*f0*kl/fs) # x[n]
for k in kl: # 求 x[k] k = 1....n
temp = 0
for l in range(0, n): # 求x[k]
cm = 1j
cm *= 2*pi*l*k/n
temp += sin(2*pi*f0*l/fs)*cmath.exp(cm)
temp = temp
yy = fft(y)
yf = abs(yy) # 用python自帶的fft驗證
對比一下python自帶fft,發現自己計算出來的結果是正確的。
其中我們會發現在20這個點特別突出,是為什麼呢?
我們會發現訊號本身是10hz的,取樣頻率是50hz,所以訊號是取樣訊號的1/5,而取樣數為100,所以這裡的20對應的頻率就是10hz。
另外在80這裡也有乙個突出,具體原因作者還沒找到,暫時猜測是因為頻譜洩露的原因,有人知道這是什麼原因麻煩告訴一下作者好嗎? 後面待我弄清楚後,再更改這一部分。
(80突出是因為fft對稱性質)
FFT與DFT,以及DFT程式
由於dft演算法太慢,fft是更加快速的演算法。import numpy as np f0,f1 0.5,2 最高頻率為f1 t 1 f0 取樣時間為最低頻率對應的週期 fs m f1 取樣頻率為最高頻率的m倍 dt 1 fs 取樣間隔 生產取樣訊號 t np.arange 0,t,dt y 3 2...
用Python實現DFT並繪製功率譜
知識背景 傅利葉變換可以分為連續傅利葉變化和離散傅利葉變換,分別是ft,fs,dtft,dtfs。其中dtft是我們常說的離散時間傅利葉變換,但這種變換並不一定能夠由計算機進行處理,因為對於非週期訊號來說其譜一般是連續譜,這樣就無法由計算機完成了。所以dft就出現了,我們知道dtft是以2 為週期的...
對於FFT和DFT的理解
此篇文章是對 ministm32f103實現家庭普通電路中的電流諧波檢測 一文的補充 本文參考 快速傅利葉變換學習及c語言實現 形象的介紹 什麼是傅利葉變換?手把手教你理解 fft fft是最重要,也是最難懂的。簡單說下原理 fft 快速傅利葉變換 是dft 離散傅利葉變換 的改進演算法,其將dft...