一、快速傅里葉介紹
傅立葉原理表明:任何連續測量的時序或信號,都可以表示為不同頻率的余弦(或正弦)波信號的無限疊加。FFT是離散傅立葉變換的快速算法,可以將一個信號變換到頻域。那其在實際應用中,有哪些用途呢?
1.有些信號在時域上是很難看出什么特征的,但是如果變換到頻域之后,就很容易看出特征(頻率,幅值,初相位);
2.FFT可以將一個信號的頻譜提取出來,進行頻譜分析,為后續濾波准備;
3.通過對一個系統的輸入信號和輸出信號進行快速傅里葉變換后,兩者進行對比,對系統可以有一個初步認識。
假設采樣頻率Fs,信號頻率F,信號長度L,采樣點數N。那么FFT之后結果就是一個為N點的復數。每一個點就對應着一個頻率點。這個點的模值,就是該頻率值下的幅度特性。
具體跟原始信號的幅度有什么關系呢?
1. 假設原始信號的峰值為A,那么FFT的結果的每個點(除了第一個點直流分量之外)的模值就是A的N/2倍,而第一個點就是直流分量(即0Hz),它的模值是直流分量的N倍;
2. 每個點的相位呢,就是在該頻率下的信號的相位。第一個點表示直流分量,它的相位是該頻率的初相位,matlab以cos為底的,若信號時正弦形式sin(t),則變成cos(t-pi/2)即可。
采樣頻率Fs,被N-1個點平均分成N等份,每個點的頻率依次增加。為了方便進行FFT運算,通常N取大於信號長度L的2的整數次方。
例如某點n所表示的頻率為:Fn=(n-1)*Fs/N。由上面的公式可以看出,Fn所能分辨到頻率為為Fs/N。如果采樣頻率Fs為1024Hz,采樣點數為1024點,則可以分辨到1Hz。
1024Hz的采樣率采樣1024點,剛好是1秒,也就是說,采樣1秒時間的信號並做FFT,則結果可以分析到1Hz。如果采樣2秒時間的信號,則N為2048,並做FFT,則結果可以分析到0.5Hz。
如果要提高頻率分辨力,則必須增加采樣點數,也即采樣時間。頻率分辨率和采樣時間是倒數關系。
假設FFT之后某點n用復數a+bi表示,該復數的模就是An=sqrt(a*a+b*b),相位就是Pn=atan2(b,a)。根據以上的結果,就可以計算出n點(n≠1,且n<=N/2)對應的信號的表達式為:An/(N/2)*cos(2*pi*Fn*t+Pn),即2*An/N*cos(2*pi*Fn*t+Pn);對於n=1點的信號,是直流分量,幅度即為A1/N。
由於FFT結果的對稱性,通常我們只使用前半部分的結果,即小於采樣頻率一半的結果。
二、例子
假設我們有一個信號,它含有5V的直流分量,頻率為50Hz、相位為-30度、幅度為7V的交流信號以及一個頻率為90Hz、相位為90度、幅度為3V的交流信號。數學表達式為:
x = 5 + 7*cos(2*pi*15*t - 30*pi/180) + 3*cos(2*pi*40*t - 90*pi/180)。
我們以128Hz的采樣率對這個信號進行采樣,總共采樣256點。按照我們上面的分析,Fn=(n-1)*Fs/N,我們可以知道,每兩個點之間的間距就是0.5Hz。我們的信號有3個頻率:0Hz、15Hz、40Hz
出於編程方便,因為直流分量的幅值A1/N,其他點幅值為An/(N/2),故直流分量最后要除以2才是對的。
一般FFT所用數據點數N與原含有信號數據點數L相同,這樣的頻譜圖具有較高的質量,可減小因補零或截斷而產生的影響。
三、Matlab代碼
Fs = 128; % 采樣頻率
T = 1/Fs; % 采樣時間
L = 256; % 信號長度
t = (0:L-1)*T; % 時間
x = 5 + 7*cos(2*pi*15*t - 30*pi/180) + 3*cos(2*pi*40*t - 90*pi/180); %cos為底原始信號
y = x + randn(size(t)); %添加噪聲
figure;
plot(t,y)
title('加噪聲的信號')
xlabel('時間(s)')
N = 2^nextpow2(L); %采樣點數,采樣點數越大,分辨的頻率越精確,N>=L,超出的部分信號補為0
Y = fft(y,N)/N*2; %除以N乘以2才是真實幅值,N越大,幅值精度越高
f = Fs/N*(0:1:N-1); %頻率
A = abs(Y); %幅值
P = angle(Y); %相值
figure;
subplot(211);plot(f(1:N/2),A(1:N/2)); %函數fft返回值的數據結構具有對稱性,因此我們只取前一半
title('幅值頻譜')
xlabel('頻率(Hz)')
ylabel('幅值')
subplot(212);plot(f(1:N/2),P(1:N/2));
title('相位譜頻')
xlabel('頻率(Hz)')
ylabel('相位')
原始信號中x = 5 + 7*cos(2*pi*15*t - 30*pi/180) + 3*cos(2*pi*40*t - 90*pi/180);
可以看到,幅值頻譜中15Hz(與數學表達式中的15Hz對應),幅值7.063(與7對應),相位頻譜中初相位-0.5072(與-30*pi/180對應)
幅值頻譜中40Hz(與數學表達式中的40Hz對應),幅值3.082(與3對應),相位頻譜中初相位-1.57(與-90*pi/180對應)
下面驗證Matlab中快速傅里葉變換是以cos為底的。
1.原始信號換為:x = 5 + 7*sin(2*pi*15*t - 30*pi/180) + 3*sin(2*pi*40*t - 90*pi/180); %sin為底的原始信號
幅值頻譜明顯對應正確,只需驗證相位頻譜。由於sin(t + p1)=cos(t + p1 - pi/2),故
-30*pi/180 - pi/2 = -2.0944,這與相位頻譜中-2.093對應
-90*pi/180 - pi/2 = -3.1416,這與相位頻譜中-3.057對應
若想提高結果的精度,可以提高信號長度L和采樣點數N。
2.原始信號若為x = 5 + 7*cos(2*pi*15*t - 30*pi/180) + 3*sin(2*pi*40*t - 90*pi/180); %sin和cos為底的原始信號
同樣驗證正確。