时频分析——短时傅里叶变换原理及实现

引言

       傅里叶变换几乎是最常用的信号处理手段,但在实际应用中,它还是存在着一些缺陷,先来看一个傅里叶变换的例子。

       仿真生成一段频率随时间变化的信号x,再将其频率变化顺序反过来,生成信号x2

fs = 1000;
t = 0 : 1/fs : 1-1/fs;
f1 = 50;
f2 = 100;
f3 = 200;
x = [1*sin(2*pi*f1*t), 2*sin(2*pi*f2*t), 4*sin(2*pi*f3*t)];
x2 = [4*sin(2*pi*f3*t), 2*sin(2*pi*f2*t), 1*sin(2*pi*f1*t)];

       它们的时域波形如下图

时频分析——短时傅里叶变换原理及实现_第1张图片

        然后对上述信号作傅里叶变换,频谱图如下

时频分析——短时傅里叶变换原理及实现_第2张图片

       显然,两者的频谱完全一样。傅里叶变换的结果表征了该信号的频率分布信息,但是并没有反映出信号频率随时间变化的规律,或者说傅里叶变换将信号转换至频域分析,缺失了时间信息,这可能无法满足某些实际应用。

       因此,时频分析应运而生,在获得信号的频率信息的同时,还能观察时间信息,有效解决了傅里叶变换的缺陷。

短时傅里叶变换  

      常用的时频分析手段便是短时傅里叶变换(Short Time Fourier Transorm),顾名思义,其思路也很容易理解:对整个序列做傅里叶变换会丢失时间信息,那么分段做傅里叶变换不就可以解决了。

       那么如何分段呢?这时候就要用到窗函数了,通过加窗的方法来截取信号的片段,常用的窗函数诸如汉宁窗、海明窗等。接下来对截取的这一段信号作傅里叶变换,然后再截取,再作傅里叶变换,直至完成所有分段。

       当然,考虑到移动窗函数时可能会丢失信号,通常会添加一个参数—重叠度(Overlap)。重叠即表示每次截取的信号会存在相同部分,不同窗函数的重叠度选取也不尽相同,如汉宁窗、海明窗一般选择为50%,感兴趣的可以自行查看。

      下面来具象化一下短时傅里叶变换的原理步骤。

1)针对某一信号序列

时频分析——短时傅里叶变换原理及实现_第3张图片

 2)选择一个窗函数以及重叠度,分段截取信号

时频分析——短时傅里叶变换原理及实现_第4张图片

 上图中,M为窗长度,L为重叠长度,R则为窗移动长度(Hop Size)。

3)然后对每段作傅里叶变换

时频分析——短时傅里叶变换原理及实现_第5张图片

 注:信号分段数可通过如下计算:

k=\left \lfloor \frac{_{Nx}-L}{M-L} \right \rfloor

式中,_{Nx}为信号长度。

代码实现

       基于上述原理及步骤,本文通过matlab实现了短时傅里叶变换,并与其自带stft接口进行了对比验证,仅供参考。

       函数输入:信号x,采样频率fs。

function [s,f,t] = stftFunc(x, fs)

%
Nx = numel(x);

%
M = 256;
overlap = 0.5;
L = overlap * M;
k = floor((Nx-L)/(M-L));
R = M - L;

%
win = hann(M);
nfft = M;

% STFT
s = zeros(k,nfft);
for i = 1 : k
    
    index = (i-1)*R+1 : (i-1)*R+M;
    xi = x(index);
    
    xw = xi.*win.';
    
    xwdft = fft(xw, nfft);
    
    xf = fftshift(xwdft);
    
    s(i,:) = xf(1:nfft);
    
end

t = (M/2 : R : M/2+(k-1)*R)/fs;

f = (-nfft/2 : nfft/2-1) * (fs/nfft);

      针对引言部分中的信号x,使用上述实现STFT函数得到其时频结果,如下图:

时频分析——短时傅里叶变换原理及实现_第6张图片

       图中可以清晰地看出频率分布随时间的变化规律。

结语

       当然,如同傅里叶变换一样,短时傅里叶变换也有着自己的缺陷,如窗长度的选取等因素会影响分析结果,感兴趣的可以深入了解或者手动测试一下。

总结不易,点个赞吧(●'◡'●)

你可能感兴趣的:(信号处理,时频分析,matlab,算法)