1. 程式人生 > >STFT原理及MATLAB程式碼

STFT原理及MATLAB程式碼

原文地址:http://blog.csdn.net/shengzhadon/article/details/46811923

一、先說說STFT的理論

1.概念和特點

STFT(short-time Fourier transform,短時傅立葉變換)是和傅立葉變換相關的一種數學變換,用以確定時變訊號其區域性區域正弦波的頻率與相位。

用途:與小波變換相似,經STFT處理後的訊號具有時域和頻域的區域性化特性(見下圖),可以藉助其分析訊號的視訊特性。


侷限:STFT的使用範圍受其變換性質的侷限。STFT是一種基於窗函式的變換,一般來說,短窗能夠提供較好的時域解析度,長窗能夠提供較好的頻域解析度。這導致其實在研究過程中,還是隻能側重一種研究角度,或稱一種側重的解析度。所以這並不是多解析度分析。這也是為什麼之後又提出了小波變換的原因之一。

2.原理簡介

以下介紹的與其說是原理,不如說時如何理解短時傅立葉變換。

顧名思義,短時傅立葉變換就是將原來的傅立葉變換在時域截短為多段分別進行傅立葉變換,每一段記為時刻ti,對應FFT求出頻域特性,就可以粗略估計出時刻ti時的頻域特性(也就是同時指導了時域和頻域的對應關係)。用於訊號截短的工具叫做窗函式(寬度相當於時間長度),窗越小,時域特性越明顯,但是此時由於點數過少導致FFT降低了精確度,導致頻域特性不明顯。因此說窗的選取(包括大小和型別)是一個博弈的過程,根據自己研究的角度,選取適合的窗即可,當然最好還是選小波變換。。。

另外,為了保證頻域特性的基礎上提高時域特性,經常選擇前後窗函式重疊一部分,這樣兩個窗確定的時刻就比較接近就提高了時域分析能力。但不是重疊越多越好,重疊點數過多會大幅增加計算量,導致效率低下,因此前後窗重疊的點數也需要外加確定。

給張圖方便理解,圖中矩形表示窗,窗確定的時刻為窗的中間時刻:

3.設計思路

對STFT已經有了初步的瞭解,那麼就開始設計吧~設計思路如下:

(1)窗函式選擇hamming窗,最大DFT點數不大於256;

(2)使用者輸入(傳值):signal, window, overlap, N, fs等;

(3)根據窗的大小,將signal拆分,並與窗函式相乘;

(4)對每個signal片段進行N點FFT,並求出能量譜密度;

(5)呼叫繪圖方法,把能量譜密度(功率譜密度)用不同的顏色表示出來繪圖。

說明:

(1)各種窗表示式

①海明窗(hamming):w(n)=0.54-0.46*cos(n/N);

②漢寧窗(hanning):w(n)=0.5*(1-cos(n/N));

③矩形窗(Rectangular):w(n)=1.0;

④三角窗(Triangle):w(n)=TRI(2n/N);

⑤布萊克曼窗(Blackman,三階升餘弦窗):w(n)=0.42-0.5*cos(n/N)+0.08*cos(2n/N);

⑥布萊克曼-哈里斯窗(BlackmanHarris):w(n)=0.35875-0.48829*cos(n/N)+0.14128*cos(2n/N)-0.01168*cos(3n/N);

(2)訊號與窗的相乘

根據窗的長度擷取響應長度的訊號序列,然後二者對應的點逐點相乘,得到的數即為加窗擷取後的值。之所以需要乘以窗函式,是因為如果直接擷取訊號,會使得擷取的訊號出現突變(波形上表現為直角),經過變換後會出現無限諧波影響擷取後FFT的效果。

(3)繪圖用到的顏色

根據能量譜密度值的不同選擇不同的顏色表示,值從低到高對應顏色從冷色到暖色變化。顏色色譜如下圖所示(冷→暖):


①在matlab中colorbar可以調出顏色條圖,如colorbar,colorbar('North')等,North表示在top出現顏色條,另外還有East, West, South等(詳見matlab幫助help colorbar);

②在matlab中colormap可以調出顏色條圖對應的RGB值陣列;

③複製一下RGB對應的陣列如下:

  1. #pragma mark - 顏色陣列
  2. //colorbar,colormap,定義冷暖色條的RGB值
  3. staticfloat g_colorBarR[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.06250,0.1250,0.18750,0.2500,0.31250,0.3750,0.43750,0.500,0.56250,0.6250,0.68750,0.7500,0.81250,0.8750,0.93750,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.93750,0.8750,0.81250,0.7500,0.68750,0.6250,0.56250,0.500};  
  4. staticfloat g_colorBarG[64] = {0,0,0,0,0,0,0,0,0.0625,0.125,0.1875,0.250,0.3125,0.375,0.4375,0.500,0.5625,0.625,0.6875,0.750,0.8125,0.875,0.9375,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9375,0.875,0.8125,0.750,0.6875,0.625,0.5625,0.500,0.4375,0.375,0.3125,0.250,0.1875,0.125,0.0625,0,0,0,0,0,0,0,0,0};  
  5. staticfloat g_colorBarB[64] = {0.5625,0.625,0.6875,0.750,0.8125,0.875,0.9375,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9375,0.875,0.8125,0.750,0.6875,0.625,0.5625,0.500,0.4375,0.375,0.3125,0.250,0.1875,0.125,0.0625,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  
(4)能量譜密度(功率譜密度PSD)

①設一個能量訊號 s(t)

的能量為E,則此訊號的能量由下式決定:


②在MATLAB中計算過程是

首先對截短的訊號分別進行FFT並求模的平方(實部平方+虛部平方),然後除以窗函式的平方和得到Sxx。根據Sxx計算第一項分量(直流分量10lg10(|Sxx/fs|))、中間項(交流分量10lg10(|2*Sxx/fs|))和最後一項(fft計算點數為奇數與中間項一致,否則與第一項一致)。

附帶matlab程式程式碼檢視方法:在command視窗輸入edit spectrogram,回車即可。

二、程式的實現

上面的介紹已經說明了設計思路,這裡就不畫流程圖,直接上程式碼了

1.spectrogram方法

本部分的程式碼完全模仿matlab做的,所以如果有什麼不明白的可以去檢視matlab原始碼。另外,本部分的程式碼沒有拆分,而是把所有的功能都用一個方法實現,自覺地給自己一個差評。。。

注:寫本部分程式碼的時候我對objc還是小白,所以基本用的都是C語言的格式。。。

  1. /** 
  2.  *  @brief   模仿MATLAB的spectrogram,實現STFT功能 
  3.  *  @param   signalVector 原始訊號序列 
  4.  *  @param   N            訊號的長度 
  5.  *  @param   win          窗長度 
  6.  *  @param   noverlap     窗重疊的點數