歡迎轉載,但請一定要給出原文鏈接,標註出處,支持原創! 謝謝~
https://blog.csdn.net/qq_29225913/article/details/105467006
1、Matlab FFT 函數介紹
FFT (Fast Fourier Transform) 中文爲快速傅里葉變換,作用是將離散的時域信號變換到頻域,在一般情況下,時域信號都比較難看出特徵,但是轉換成頻域後,就比較容易看出來,因此,很多信號分析都會採用FFT變換,然後對信號進行頻譜分析。
Matlab 中,FFT 函數的語法如下:
Y = fft(X)
Y = fft(X,n)
Y = fft(X,n,dim)
推薦直接在命令行使用 help fft
看到更加詳細的描述信息與例程,這裏主要記錄一下用法以及注意事項。
N個採樣點,經過FFT之後,就可以得到N個點的FFT結果。爲了方便進行FFT運算,通常N取2的整數次方,但是這裏直接取讀取出來的樣本數作爲N。
- FFT 計算公式如下:
- Xk 長度與 N 相同。
- 根據奈科斯特定律,只有 f=fs/2 範圍內的信號纔是被採樣到的有效信號,因此得到的頻譜肯定是關於 N/2 對稱的(就是隻看前一半的波形就好)。
- 第k點的實際頻率的計算爲 f(k) = k * (fs / n) — — (橫軸的頻率範圍爲 :f = n * fs / N;)
- X[0] 爲直流分量 ,幅值 = 模值(X[0]) / N
- X[k] 爲個點的頻率分量(除X[0]外),幅值 = 模值(X[k]) / (N / 2)
2、Matlab FFT 程序
-
先擺上代碼,運行一下看效果。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 功能:FFT 運用方法(例程) % % 作者:Mr-Ma Technology(馬健維) % % 時間:2020.04.12 % % 轉載請註明出處 % % https://blog.csdn.net/qq_29225913/article/details/105467006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 描述 % 使用 Matlab 的 FFT,有一個注意事項,採樣數量是採樣頻率的整數倍,且最好是 2 的 n 次冪。 % 否則會導致採樣分辨率匹配不上,表現爲在對應的頻點處沒有采樣到,出現偏移,因此會導致 % 描繪圖像時,發現所需要的頻點處顯示出來的幅度值小於預期的值。 % 可以通過修改參數定義的值得定義來直觀的看FFT的效果 %% 參數定義 A1 = 2; % 信號1 幅值(A) f1 = 11; % 信號1 頻率(f) A2 = 0.5; % 信號2 幅值(A) f2 = 29; % 信號2 頻率(f) A3 = 1; % 信號3 幅值(A) f3 = 51; % 信號3 頻率(f) Dc = 0; % 直流分量 Noise = 0; % 噪聲大小 fs = 128; % 採樣頻率 (fs) N = 1024; % 採樣點數(樣本數量) %% 運算(生成時域曲線、FFT計算) n = 0:N-1; % 等差生成序列, t = n / fs; % 時間序列,用於下式 RA = rand(1,N); % 隨機噪聲(0~1) RA = RA - mean(RA); % 減去噪聲均值(-0.5~0.5),去除噪聲中的直流分量。 x = Dc + A1 * sin(2*pi*f1*t) + A2 * sin(2*pi*f2*t) + A3 * sin(2*pi*f3*t)+ Noise * RA ; % 兩個正弦信號、直流分量、噪聲 相疊加 y = abs(fft(x,N)); % 對上式進行 N 點 FFT 計算 ,並取模值 A = y * 2 / N; % 模值轉換爲幅值 A(1) = A(1) / 2; % 根據公式 ,X[0] 不用乘以 2 f = n * fs / N; % 轉換爲頻率區間 %% 繪圖 subplot(2,1,1); plot(t,x); xlabel('時間/s');ylabel('振幅'); title('時域曲線') subplot(2,1,2); plot(f(1:N/2),A(1:N/2)); % 描繪圖像 xlabel('頻率/Hz');ylabel('振幅'); title(['幅頻特性曲線 :Fs = ',num2str(fs),', N = ',num2str(N)])
-
運行圖片:
3、FFT 程序分析
通過運行上面的代碼,可以得到與上圖一致的運行效果,該程序中,原函數是由 直流分量、信號1、信號2、信號3、噪聲分量 疊加而成的(上圖中暫時將直流分量與噪聲分量設置爲0),在實際工程使用中,將例程中生成的原函數替換成需要進行分析的序列就可以了。
上面的圖片中,每一個信號的幅值就剛好等於所設置的振幅,此處有一個地方需要注意的就是,一般情況下,採樣點 N 都不固定,都是隨輸入的因素影響,例如對一首採樣率爲 44.1KHz 的歌來分析,讀取出來的數據長度 N 就不一定是 2 的n次方了,如果直接送入進行 FFT 計算,到 N 點結算數據,在FFT內由於使用蝶形運算,所以是需要 N 是 2 的 n 次方,因此會導致在 N 個採樣點後方補零, 可能在某些頻點出看到的賦值,會比預想值要小,這就是能量泄露。如果只需要考慮各頻譜值得比例(即只看頻率分佈情況),不考慮實際 FFT 後的幅值的話,可以直接傳入N進去,如果需要進行頻譜分析,就要要考慮實際的幅值對分析結果的影響,此處就可以選擇加窗,還有一種情況就是 N 足夠大,並且是均勻分佈,就可以考慮截取 N 的值,使得滿足 N 等於 2 的 n 次方。
3.1 fs 、N 對 FFT 圖像幅值的影響。
上述程序中,fs = 128;N = 4096;(N 是 fs 的整數倍,且 N 是 2 的 n 次方),下面來分析下不同的 fs 與 N 對實際 FFT 結果的影響。
- 1、 fs = 100,N = 100(這個情況下,信號 3 不滿足 fs ≥ 2f 的情況,因此信號 3 不會顯示出來)
- 2、 增大 N ,fs = 100,N = 150,由於補零了,所以存在能量泄漏,計算出來的幅值會變小。
- 3、 增大Fs,fs = 200,N=150,此時由於 N 與 fs 仍然是非整數倍關係,且樣本數量不足夠大,導致分辨率不足,使得不能夠將所有的頻率都能夠對應上,造成頻率泄漏,導致幅值變小。
- 4、 繼續加大 N ,直接擴大10倍,fs = 200,N = 1500,可以觀察到隨着樣本數量增加的時候,幅頻特性曲線會變窄,與實際的頻率越接近,即精度越高。但是由於 fs 與 N 仍然非整數倍關係,因此仍然會有上一點存在的問題。
- 5、 這一步,減少 N ,但是設置爲 fs 的整數倍(往上滑,與第1點對比),fs = 100, N = 200,可以看出,與第 1 點對比的時候,幅值依然是實際值,但是精度更高了(由於N 的數多了一倍)
- 6、 (對照組)擴大 N 爲 fs 的 2 倍(與第 3 、5 點對比)fs = 200,N= 400,因爲同樣 N 是 fs 的整數倍,幅值爲實際值。
- 7、 最後,設置 fs、N 均爲 2 的 n 次方,這裏的 fs 根據最高信號頻率來選擇即可,比如信號 3 是頻率最高的信號(51Hz),因此 fs 選擇128,N儘量的大,因此 N 選擇 4096,此時時域信號中的頻率信息,都能夠很好的表示出來。
3.2 直流分量、噪聲分量對 FFT 圖像的影響
在這一節考慮將直流分量,與噪聲信號加入,通過改變以下兩項來加入。其他值使用默認的參數(fs = 128,N = 1024)
- 設置直流分量爲1,可以看到 FFT 圖像 x = 0 處有一個直流分量。(實際使用中,直流分量對信號的分析用處不大,所以一般都會將此值設爲0,或者將 用
x = x - mean(x)
的方法,將直流分量過濾掉)
按照直流分量的計算公式,需要在程序裏對該值進行修改(幅值 = 模值 / N ; 當 x = 0)
- 修改噪聲分量的值 爲10,(即疊加一個 幅度爲 ±5 的噪聲信號),使用噪聲前,需要對噪聲進行消除直流處理。
可以看出來,在時域的圖像上,已經看不清信號的內容了,但是在頻域上,仍然能夠分辨的出有3個主要信號,並且在採樣範圍內,均勻分佈着噪聲信號。後面可以通過設計帶通濾波器,將3個有用信號的頻段提取出來,其他頻段的信號進行過濾,在利用 IFFT 還原出降噪後的波形。
3.3 總結
- 在能夠自己選定 fs 的情況下,儘量選擇 fs 爲 2 的 n 次方,且 N 取 fs 的倍數,這樣可以在幅頻特性曲線上,得到與實際相符的幅度值。
- fs 固定的情況下,(如音頻文件,44.1K/48K/…),不能修改fs,則選擇 N 爲 fs 的整數倍,通常這種情況下 N 的數量都會足夠大,因此 N 向前截取(即N值 ≤ 實際採樣點)默認信息是隨機分佈,最後的一節信號不會對整體的頻譜產生較大的影響。(若要考慮全部採樣點,則可忽略對實際幅值的影響,實際幅值不一定需要)
- 疊加噪聲的分析,可以轉換到頻域上進行處理。