傅里葉變換終極必殺技

網上關於傅里葉變換的解釋特別多,但大部分都比較偏理論,導致我看來N多教程也還是懵懵懂懂。在某本書(信號完整性分析???)中看到一句震耳發聵的話:"每個工程師都應該親自動手計算一遍傅里葉變換"。

我知道很多工具可以直接給出傅里葉變換結果,但不清不楚一直是我心裏過不去的坎,今天終於把坎踏平了,已經忘記了這是第幾次衝鋒。。。20200324

本文主要對一個連續週期信號進行採樣所得的有限離散週期信號進行離散傅里葉變換(DFT)變換,期間對用到的一些原理進行解釋說明並有詳細計算過程。基本包括了處理過程的所有細節。

這裏說明一下:快速傅里葉變換FFT是一種利用矩陣知識快速實現離散傅里葉變換DFT的方法,最終結果是一樣的,FFT只是一種實現DFT的算法

首先假設我們已經瞭解了以下理論知識:

  1. 採樣定理(採樣頻率至少要大於原始信號最高頻率的2倍才能提取出原始信號信息);
  2. 歐拉公式的應用:   

假設我們的原始信號是:

                                    

計算出上面兩個正弦函數的週期分別是1 s和 2/3 s,所以函數 Xt 的週期是2 s(最小公倍數)。

根據採樣定理,我們的採樣頻率就至少需要0.5 Hz才能保證這兩個頻率都被正確處理(採樣頻率越高,失真越小)。我們這裏就定採樣頻率Fs爲4 Hz吧(即每相鄰兩個採樣點的採樣時間間隔是0.25 s ,剛好兩倍的採樣頻率結果觀察起來不夠明顯)。

確定了採樣頻率,接下來就是採樣點的個數了。對於週期信號,要使採樣後的信號能完全還原出來,採樣的範圍必須至少包含一個週期吧。函數 Xt 的週期是2 s,採樣頻率4 Hz,於是得出採樣點數N至少爲8點。

下面開始計算啦!!!

傅里葉變換計算公式爲:

                            

上式的就是我們採樣點的值,就是傅里葉變換的結果。或許很多人看到這個式子這麼複雜就頭大,我也是[哭唧唧]。但我們的偉大領袖說過“一切數學公式都是紙老虎”。且看我將它大卸八塊。(對於想要從感性上理解這個公式的同學,強烈建議上B站學習一下:https://www.bilibili.com/video/BV1pW411J7s8?from=search&seid=7806809382090131811

我們這裏就只講計算了,畢竟理論的東西我自己還不能說很懂呢。。。

因爲要用到,那我們就先要把  都計算出來:

                    第一個點:    = sin(2*pi*0) + sin(3*pi*0) + 1 = 1

                    第二個點:     = sin(2*pi*0.25) + sin(3*pi*0.25) + 1 =   2.7071

                    第三個點:    = sin(2*pi*0.5) + sin(3*pi*0.5) + 1 =   0

                    第四個點:    = sin(2*pi*0.75) + sin(3*pi*0.75) + 1 =   0.70711

                    第五個點:    = sin(2*pi*1) + sin(3*pi*1) + 1 =   1

                    第六個點:    = sin(2*pi*1.25) + sin(3*pi*1.25) + 1 =   1.2929

                    第七個點:    = sin(2*pi*1.5) + sin(3*pi*1.5) + 1 =   2

                    第八個點:    = sin(2*pi*1.75) + sin(3*pi*1.75) + 1 =   -0.70711

好了現在可以開始計算傅里葉變換了:(N = 8)

                

                    

(雖然看起來上面的計算狠複雜(其實真的很複雜呀),但至少上面沒有未知數,結果是一定存在的,不管是按計算器,matlab工具,或者歐拉公式,只有能計算出正確結果,就是好方法。)

堅持住,到了這裏基本就要結束啦!

接下來對結果稍加整理,就是我們需要的頻譜圖啦!

由:           可得:

                      

根據上面推薦的B站視頻可知,傅里葉變換是計算的N個點的向量和,所以之前計算得到的結果要除以採樣點數N,abs是求模長(絕對值)的函數,因爲頻譜圖縱座標的幅值是正值。(好吧我知道解釋的很牽強,其實我也不知道爲啥要這樣。。。這個教程只負責指導你親手計算一次傅里葉變換,關於理論知識,其他教程說的比我精彩)

上面就是頻譜圖的一些點了,但是我怎麼知道每一個點對應什麼頻率呢?

其實傅里葉變換後的頻率分辨率是(其中爲採樣的總時長)。爲啥呢?

對以上的結果可以理解爲:我們採樣的數據只有 秒,信號的成分中週期最大也就是秒,頻率最低就是那麼頻率分辨率就是 了。也就是說頻率分辨率只和總採樣時間有關。採樣時間越長,能區分的頻率就越小,即分辨率越好。

這裏假設採樣週期爲T,採樣總時長爲,那麼就有如下關係:

                                          

本例子中解釋分辨率就是:傅里葉變換的第一個結果表示頻率爲0的信號幅值,第二個結果就是表示頻率爲Fs/N = 4/8 = 0.5Hz 的信號幅值了,依次第三個結果表示1Hz信號幅值。。。第八個表示頻率爲3.5Hz信號的幅值。

我們把上面的結果在座標軸中畫出來,就是我們說的頻譜圖啦:(Fs = 4Hz, N = 8, 對稱處理前

                                

我們發現f=0.5到f=3.5的結果關於f=2對稱,即X(N-k) = X(k)   (其中k=1:N-1)。

(對稱的理論證明,傳送門在此:https://www.zhihu.com/question/264560305

我們看頻率爲0的時候幅值爲1,表示原始信號中有一個幅值爲1的直流信號,和我們的給出的原始信號相符(加了一個常數1)。

頻譜圖中頻率爲1時幅值是0.5,但我們的原始信號頻率爲1( sin(2*pi*t) )的分量幅值可是1啊。這是爲啥呢?這是由上面說的對稱所引起的。頻譜圖中頻率爲1和頻率爲3的點對稱,兩個點幅值都是0.5,兩個加起來,就剛好是原始信號的幅值1了。同理sin(3*pi*t)的幅值是由頻譜圖中頻率爲1.5Hz和頻率爲2.5Hz的兩個幅值相加而來,幅值也是1。

但圖形既然對稱,爲啥我們要選擇相信原始信號是由頻率爲1Hz和頻率爲1.5Hz的正弦波合成的,而不是頻率爲2.5Hz和3Hz呢?我們的採樣頻率是4Hz,根據採樣定理,最大隻能處理到2Hz的情況,所以我們只能選擇1Hz和1.5Hz啦。

上面已經是頻譜圖了,但是不夠完美,既然我們只需要對稱的前半部分,那就再處理一下吧:

我們只取上面結果的頻率在2Hz前的部分,且對頻率不爲0的信號幅值加倍,就得到了最終結果:(Fs = 4Hz, N = 8

                               

怎麼樣,這個結果夠完美了吧!!!

但是這個實驗的採樣點太少導致頻率分辨率太低(頻率爲0.75的幅值是什麼呢,我們不知道,圖中只是把前後兩個點連線過渡而已,並不表示中間區域的幅值。注意:週期信號在頻域中一定是離散的)。

頻率分辨率太低怎麼辦呢? 根據之前的分析知道,需要加長總的採樣時間,那就保持採樣頻率不變,採樣點數加到16試試吧,結果如下:(Fs = 4Hz, N = 16

                                      

現在,從圖中我們已經可以看出頻率爲0.75的信號分量幅值爲0,基本能夠確定原始信號中只有這三個波峯對應的頻率分量了。

再把採樣點加到512個點,結果如下:(Fs = 4Hz, N = 512

                                  

這下夠清楚了吧。。。

 

在此附上matlab代碼:( %後跟註釋,如有需要可以刪除%查看中間結果,但中文前面的那個%不能刪除)

-------------------------程序開始(可在線運行https://octave-online.net/ )------------------------------

Fs = 4;                                % 設置採樣率

T = 1/Fs;                            % 採樣週期

N = 512;                            % 設置採樣點數,設爲8即可得到上面的實驗結果

t = (0:N-1)*T;                   % 確定採樣值,: 表示變量的取值範圍

%t                                       % matlab中變量不加分號時會打印出變量的值

y = sin(2*pi*t)+sin(3*pi*t)+1;     % 本例子的原始信號,可以看出f = 0Hz, f=1Hz, f=1.5Hz 的信號分量

%y

Y = fft(y);                           % FFT是通過矩陣計算傅里葉變換的一種算法,和DFT結果是一樣的

%Y                                      % 把Y前面的百分號去掉,就可以快速得到上面的計算結果啦!

Y1 = Y/N;                           % 上面有說,我也不知道爲啥要除以N

%Y1

P2 = abs(Y1);                    % 求複數的模長

%P2

%f = Fs*(0:N-1)/N;          % 頻率分辨率爲Fs/N,  頻率範圍是0到Fs(N-1)/N

%plot(f,P2);                      % 以f爲x軸座標的格點,畫出對稱的變換結果

%xlabel('frequens(Hz)');              % 設置x軸座標名稱

%ylabel('amplifer');                      % 設置y軸座標名稱

%title('DFT result for \"y=sin(2*pi*t)+sin(3*pi*t)+1\"');                 % 設置圖像標題

P1 = P2(1:N/2+1);                          % 把對稱的部分圖形去掉

%P1

P1(2:end-1) = 2*P1(2:end-1);      % 從第二個結果開始幅值都加倍(end表示最後一個值)

%P1

f = Fs*(0:N/2)/N;                           % 頻率分辨率爲Fs/N,  頻率範圍是0到Fs/2

%f

plot(f,P1);                                       %以f爲x軸座標的格點,畫出去掉對稱部分的變換結果

xlabel('frequens(Hz)');

ylabel('amplifer');

title('DFT result for \"y=sin(2*pi*t)+sin(3*pi*t)+1\"');

-------------------------------------------------程序完------------------------------------------------------------

恭喜我們都學習完啦,寫這篇總結的時候對傅里葉變換也有了更深刻的認識,好開心呀!

本文參考的資料如下:

https://ww2.mathworks.cn/help/matlab/ref/fft.html

             

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章