使用python實現(xiàn)快速傅里葉變換(FFT)

說明:本文適合信號處理方面有一定的基礎的人閱讀琅捏,能夠理解什么時候傅里葉級數(shù)和傅里葉變換,能夠理解他們的核心思想以及基本原理递雀,能夠理解到底什么是“頻率域”柄延,能夠從頻率的角度分析信號。

一缀程、一些關鍵概念的引入

1搜吧、離散傅里葉變換(DFT)

離散傅里葉變換(discrete Fourier transform) 傅里葉分析方法是信號分析的最基本方法,傅里葉變換是傅里葉分析的核心杨凑,通過它把信號從時間域變換到頻率域滤奈,進而研究信號的頻譜結(jié)構(gòu)和變化規(guī)律。但是它的致命缺點是:計算量太大撩满,時間復雜度太高蜒程,當采樣點數(shù)太高的時候绅你,計算緩慢,由此出現(xiàn)了DFT的快速實現(xiàn)昭躺,即下面的快速傅里葉變換FFT忌锯。

2、快速傅里葉變換(FFT)

計算量更小的離散傅里葉的一種實現(xiàn)方法领炫。詳細細節(jié)這里不做描述偶垮。

3、采樣頻率以及采樣定理

采樣頻率:采樣頻率帝洪,也稱為采樣速度或者采樣率似舵,定義了每秒從連續(xù)信號中提取并組成離散信號的采樣個數(shù),它用赫茲(Hz)來表示碟狞。采樣頻率的倒數(shù)是采樣周期或者叫作采樣時間啄枕,它是采樣之間的時間間隔婚陪。通俗的講采樣頻率是指計算機每秒鐘采集多少個信號樣本族沃。

采樣定理:所謂采樣定理 ,又稱香農(nóng)采樣定理泌参,奈奎斯特采樣定理脆淹,是信息論,特別是通訊與信號處理學科中的一個重要基本結(jié)論沽一。采樣定理指出盖溺,如果信號是帶限的,并且采樣頻率高于信號帶寬的兩倍铣缠,那么烘嘱,原來的連續(xù)信號可以從采樣樣本中完全重建出來。

定理的具體表述為:在進行模擬/數(shù)字信號的轉(zhuǎn)換過程中蝗蛙,當采樣頻率fs大于信號中最高頻率fmax的2倍時,即

fs>2*fmax

采樣之后的數(shù)字信號完整地保留了原始信號中的信息蝇庭,一般實際應用中保證采樣頻率為信號最高頻率的2.56~4倍;采樣定理又稱奈奎斯特定理捡硅。

4哮内、如何理解采樣定理?

在對連續(xù)信號進行離散化的過程中壮韭,難免會損失很多信息北发,就拿一個簡單地正弦波而言,如果我1秒內(nèi)就選擇一個點喷屋,很顯然琳拨,損失的信號太多了,光著一個點我根本不知道這個正弦信號到底是什么樣子的屯曹,自然也沒有辦法根據(jù)這一個采樣點進行正弦波的還原狱庇,很明顯寄疏,我采樣的點越密集,那越接近原來的正弦波原始的樣子僵井,自然損失的信息越少陕截,越方便還原正弦波。故而

采樣定理說明采樣頻率與信號頻率之間的關系批什,是連續(xù)信號離散化的基本依據(jù)农曲。 它為采樣率建立了一個足夠的條件,該采樣率允許離散采樣序列從有限帶寬的連續(xù)時間信號中捕獲所有信息驻债。

二乳规、使用scipy包實現(xiàn)快速傅里葉變換

本節(jié)不會說明FFT的底層實現(xiàn),只介紹scipy中fft的函數(shù)接口以及使用的一些細節(jié)合呐。

1暮的、產(chǎn)生原始信號——原始信號是三個正弦波的疊加

import numpy as np
from scipy.fftpack import fft,ifft
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl 
mpl.rcParams['font.sans-serif'] = ['SimHei']   #顯示中文mpl.rcParams['axes.unicode_minus']=False       #顯示負號  
#采樣點選擇1400個,因為設置的信號頻率分量最高為600赫茲淌实,根據(jù)采樣定理知采樣頻率要大于信號頻率2倍冻辩,所以這里設置采樣頻率為1400赫茲(即一秒內(nèi)有1400個采樣點,一樣意思的)
x=np.linspace(0,1,1400)       
#設置需要采樣的信號拆祈,頻率分量有200恨闪,400和600
y=7*np.sin(2*np.pi*200*x) + 5*np.sin(2*np.pi*400*x)+3*np.sin(2*np.pi*600*x)

這里原始信號的三個正弦波的頻率分別為,200Hz放坏、400Hz咙咽、600Hz,最大頻率為600赫茲。根據(jù)采樣定理淤年,fs至少是600赫茲的2倍钧敞,這里選擇1400赫茲,即在一秒內(nèi)選擇1400個點麸粮。

原始的函數(shù)圖像如下:

plt.figure()
plt.plot(x,y)   
plt.title('原始波形') 
plt.figure()
plt.plot(x[0:50],y[0:50])   
plt.title('原始部分波形(前50組樣本)')
plt.show()

由圖可見溉苛,由于采樣點太過密集,看起來不好看豹休,我們只顯示前面的50組數(shù)據(jù)炊昆,如下:

2、快速傅里葉變換

其實scipy和numpy一樣威根,實現(xiàn)FFT非常簡單凤巨,僅僅是一句話而已,函數(shù)接口如下:

from scipy.fftpack import fft,ifft

from numpy import fft,ifft

其中fft表示快速傅里葉變換洛搀,ifft表示其逆變換敢茁。具體實現(xiàn)如下:

fft_y=fft(y)                          #快速傅里葉變換
print(len(fft_y))
print(fft_y[0:5])
'''
運行結(jié)果如下:
1400
[-4.18864943e-12+0.j   9.66210986e-05-0.04305756j   
3.86508070e-04-0.08611996j    8.69732036e-04-0.12919206j    
1.54641157e-03-0.17227871j]
'''

我們發(fā)現(xiàn)以下幾個特點:

(1)變換之后的結(jié)果數(shù)據(jù)長度和原始采樣信號是一樣的

(2)每一個變換之后的值是一個復數(shù),為a+bj的形式留美,那這個復數(shù)是什么意思呢彰檬?

我們知道伸刃,復數(shù)a+bj在坐標系中表示為(a,b),故而復數(shù)具有模和角度逢倍,我們都知道快速傅里葉變換具有

“振幅譜”“相位譜”捧颅,它其實就是通過對快速傅里葉變換得到的復數(shù)結(jié)果進一步求出來的,

那這個直接變換后的結(jié)果是不是就是我需要的较雕,當然是需要的碉哑,在FFT中,得到的結(jié)果是復數(shù)亮蒋,

(3)FFT得到的復數(shù)的模(即絕對值)就是對應的“振幅譜”扣典,復數(shù)所對應的角度,就是所對應的“相位譜”慎玖,現(xiàn)在可以畫圖了贮尖。

3、FFT的原始頻譜

N=1400x = np.arange(N)           # 頻率個數(shù) 
abs_y=np.abs(fft_y)                # 取復數(shù)的絕對值趁怔,即復數(shù)的模(雙邊頻譜)
angle_y=np.angle(fft_y)              #取復數(shù)的角度 
plt.figure()
plt.plot(x,abs_y)   
plt.title('雙邊振幅譜(未歸一化)') 
plt.figure()
plt.plot(x,angle_y)   
plt.title('雙邊相位譜(未歸一化)')
plt.show()

顯示結(jié)果如下:

雙邊振幅譜(未歸一化)
雙邊相位譜(未歸一化)

注意:我們在此處僅僅考慮“振幅譜”湿硝,不再考慮相位譜。

我們發(fā)現(xiàn)痕钢,振幅譜的縱坐標很大图柏,而且具有對稱性,這是怎么一回事呢任连?

關鍵:關于振幅值很大的解釋以及解決辦法——歸一化取一半處理

比如有一個信號如下:

Y=A1+A2cos(2πω2+φ2)+A3cos(2πω3+φ3)+A4*cos(2πω4+φ4)

經(jīng)過FFT之后,得到的“振幅圖”中例诀,

第一個峰值(頻率位置)的模是A1的N倍随抠,N為采樣點,本例中為N=1400繁涂,此例中沒有拱她,因為信號沒有常數(shù)項A1

第二個峰值(頻率位置)的模是A2的N/2倍,N為采樣點扔罪,

第三個峰值(頻率位置)的模是A3的N/2倍秉沼,N為采樣點,

第四個峰值(頻率位置)的模是A4的N/2倍矿酵,N為采樣點唬复,

依次下去......

考慮到數(shù)量級較大,一般進行歸一化處理全肮,既然第一個峰值是A1的N倍敞咧,那么將每一個振幅值都除以N即可

FFT具有對稱性,一般只需要用N的一半辜腺,前半部分即可休建。

4乍恐、將振幅譜進行歸一化和取半處理

先進行歸一化

normalization_y=abs_y/N            #歸一化處理(雙邊頻譜)plt.figure()
plt.plot(x,normalization_y,'g')
plt.title('雙邊頻譜(歸一化)',fontsize=9,color='green')
plt.show()

結(jié)果為:

雙邊頻譜(歸一化)

現(xiàn)在我們發(fā)現(xiàn),振幅譜的數(shù)量級不大了测砂,變得合理了茵烈,

接下來進行取半處理:

half_x = x[range(int(N/2))]                                  #取一半?yún)^(qū)間
normalization_half_y = normalization_y[range(int(N/2))]      #由于對稱性,只取一半?yún)^(qū)間(單邊頻譜)
plt.figure()
plt.plot(half_x,normalization_half_y,'b')
plt.title('單邊頻譜(歸一化)',fontsize=9,color='blue')
plt.show()
單邊頻譜(歸一化)'

這就是我們最終的結(jié)果砌些,需要的“振幅譜”瞧毙。

PS:還需要注意fft的第0個數(shù)據(jù),是表示直流分量寄症,本例中沒有宙彪,大部分情況不考慮第0個數(shù)據(jù)

三、完整代碼

import numpy as npfrom scipy.fftpack import fft,ifftimport matplotlib.pyplot as pltfrom matplotlib.pylab import mpl mpl.rcParams['font.sans-serif'] = ['SimHei']   #顯示中文mpl.rcParams['axes.unicode_minus']=False       #顯示負號 #采樣點選擇1400個有巧,因為設置的信號頻率分量最高為600赫茲释漆,根據(jù)采樣定理知采樣頻率要大于信號頻率2倍,所以這里設置采樣頻率為1400赫茲(即一秒內(nèi)有1400個采樣點篮迎,一樣意思的)x=np.linspace(0,1,1400)       #設置需要采樣的信號男图,頻率分量有200,400和600y=7*np.sin(2*np.pi*200*x) + 5*np.sin(2*np.pi*400*x)+3*np.sin(2*np.pi*600*x) fft_y=fft(y)                          #快速傅里葉變換 N=1400x = np.arange(N)             # 頻率個數(shù)half_x = x[range(int(N/2))]  #取一半?yún)^(qū)間 abs_y=np.abs(fft_y)                # 取復數(shù)的絕對值甜橱,即復數(shù)的模(雙邊頻譜)angle_y=np.angle(fft_y)            #取復數(shù)的角度normalization_y=abs_y/N            #歸一化處理(雙邊頻譜)                              normalization_half_y = normalization_y[range(int(N/2))]      #由于對稱性逊笆,只取一半?yún)^(qū)間(單邊頻譜) plt.subplot(231)plt.plot(x,y)   plt.title('原始波形') plt.subplot(232)plt.plot(x,fft_y,'black')plt.title('雙邊振幅譜(未求振幅絕對值)',fontsize=9,color='black')  plt.subplot(233)plt.plot(x,abs_y,'r')plt.title('雙邊振幅譜(未歸一化)',fontsize=9,color='red')  plt.subplot(234)plt.plot(x,angle_y,'violet')plt.title('雙邊相位譜(未歸一化)',fontsize=9,color='violet') plt.subplot(235)plt.plot(x,normalization_y,'g')plt.title('雙邊振幅譜(歸一化)',fontsize=9,color='green') plt.subplot(236)plt.plot(half_x,normalization_half_y,'blue')plt.title('單邊振幅譜(歸一化)',fontsize=9,color='blue') plt.show() 
匯總
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市岂傲,隨后出現(xiàn)的幾起案子难裆,更是在濱河造成了極大的恐慌,老刑警劉巖镊掖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乃戈,死亡現(xiàn)場離奇詭異,居然都是意外死亡亩进,警方通過查閱死者的電腦和手機症虑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來归薛,“玉大人谍憔,你說我怎么就攤上這事≈骷” “怎么了习贫?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長崇猫。 經(jīng)常有香客問我沈条,道長,這世上最難降的妖魔是什么诅炉? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任蜡歹,我火速辦了婚禮屋厘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘月而。我一直安慰自己汗洒,他們只是感情好,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布父款。 她就那樣靜靜地躺著溢谤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪憨攒。 梳的紋絲不亂的頭發(fā)上世杀,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音肝集,去河邊找鬼瞻坝。 笑死,一個胖子當著我的面吹牛杏瞻,可吹牛的內(nèi)容都是我干的所刀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼捞挥,長吁一口氣:“原來是場噩夢啊……” “哼浮创!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砌函,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤斩披,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胸嘴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雏掠,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年劣像,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摧玫。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡耳奕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诬像,到底是詐尸還是另有隱情屋群,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布坏挠,位于F島的核電站芍躏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏降狠。R本人自食惡果不足惜对竣,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一庇楞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧否纬,春花似錦吕晌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膜廊,卻和暖如春乏沸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爪瓜。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工蹬跃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钥勋。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓炬转,卻偏偏與公主長得像,于是被迫代替她去往敵國和親算灸。 傳聞我的和親對象是個殘疾皇子扼劈,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 快速傅里葉變換(FFT) 離散傅里葉變換(DFT) 基礎理論是傅里葉變換的分離形式,和采樣定理(香菜定理) 采樣定...
    DUTZCS閱讀 2,784評論 0 1
  • 采樣定理:所謂采樣定理 菲驴,又稱香農(nóng)采樣定理荐吵,奈奎斯特采樣定理,是信息論赊瞬,特別是通訊與信號處理學科中的一個重要基本結(jié)...
    dingtom閱讀 1,796評論 0 0
  • 對于通信和信號領域的同學來說先煎,傅里葉變換、信號采樣定理一定不陌生巧涧。本文主要對傅里葉變換中涉及的時頻關系對應進行說明...
    in469閱讀 4,249評論 0 0
  • 傅里葉變換 傅里葉變換(Fourier Transform薯蝎,簡稱FT)常用于數(shù)字信號處理,它的目的是將時間域上的信...
    lk311閱讀 1,885評論 0 2
  • 一谤绳、傅立葉變換的由來 關于傅立葉變換占锯,無論是書本還是在網(wǎng)上可以很容易找到關于傅立葉變換的描述,但是大都是些故弄玄虛...
    constant007閱讀 4,432評論 1 10