DFT 理解與python實現

2021-09-13 09:47:33 字數 2440 閱讀 6507

我們知道傅利葉變換能夠將時域的訊號變換到頻域分析,但是我們在計算機應用時,常常是離散的訊號。如,用adc採集回來的模擬訊號,就變成了離散的訊號。這時我們要對訊號進行分析,就不能再使用傅利葉變換了,而要使用離散傅利葉變換,dft:

x [k

]=∑n

=0n−

1x[n

]e−j

2π∗k

n/nx[k]=\sum_^x[n]e^

x[k]=∑

n=0n

−1​x

[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...