时频分析是现代信号处理的核心技术之一,旨在同时描述信号在时间和频率域的局部特性。传统的傅里叶变换虽然能够完美描述信号的频域特征,但其全局性质使其无法处理非平稳信号的时变特性。短时傅里叶变换通过引入窗函数的概念,在保持傅里叶变换优良性质的同时,实现了时频域的局部化分析,为非平稳信号处理提供了重要的理论工具。
STFT自1946年由Gabor提出以来,经过几十年的发展,已成为信号处理、通信、语音识别、生物医学工程等领域的重要分析方法。
设 L2(R)L^2(\mathbb{R})L2(R) 为实数轴上的平方可积函数空间,配备内积:
⟨f,g⟩=∫−∞∞f(t)g(t)‾ dt\langle f, g \rangle = \int_{-\infty}^{\infty} f(t) \overline{g(t)} \, dt⟨f,g⟩=∫−∞∞f(t)g(t)dt
其中 g(t)‾\overline{g(t)}g(t) 表示 g(t)g(t)g(t) 的复共轭。相应的范数定义为:
∥f∥2=⟨f,f⟩=(∫−∞∞∣f(t)∣2 dt)1/2\|f\|_2 = \sqrt{\langle f, f \rangle} = \left(\int_{-\infty}^{\infty} |f(t)|^2 \, dt\right)^{1/2}∥f∥2=⟨f,f⟩=(∫−∞∞∣f(t)∣2dt)1/2
对于函数 f(t)∈L2(R)f(t) \in L^2(\mathbb{R})f(t)∈L2(R),其傅里叶变换定义为:
f^(ω)=F{f}(ω)=∫−∞∞f(t)e−iωt dt\hat{f}(\omega) = \mathcal{F}\{f\}(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} \, dtf^(ω)=F{f}(ω)=∫−∞∞f(t)e−iωtdt
傅里叶变换满足Parseval等式:
∥f∥22=12π∥f^∥22\|f\|_2^2 = \frac{1}{2\pi} \|\hat{f}\|_2^2∥f∥22=2π1∥f^∥22
然而,傅里叶变换的全局性质意味着 f^(ω)\hat{f}(\omega)f^(ω) 包含了信号 f(t)f(t)f(t) 在整个时间轴上的频率信息,无法提供频率成分的时间局部化信息。
对于信号 f(t)∈L2(R)f(t) \in L^2(\mathbb{R})f(t)∈L2(R) 和窗函数 w(t)∈L2(R)w(t) \in L^2(\mathbb{R})w(t)∈L2(R),短时傅里叶变换定义为:
Vwf(t,ω)=⟨f,wt,ω⟩=∫−∞∞f(τ)w(τ−t)‾e−iωτ dτV_w f(t, \omega) = \langle f, w_{t,\omega} \rangle = \int_{-\infty}^{\infty} f(\tau) \overline{w(\tau - t)} e^{-i\omega\tau} \, d\tauVwf(t,ω)=⟨f,wt,ω⟩=∫−∞∞f(τ)w(τ−t)e−iωτdτ
其中 wt,ω(τ)=w(τ−t)eiωτw_{t,\omega}(\tau) = w(\tau - t) e^{i\omega\tau}wt,ω(τ)=w(τ−t)eiωτ 为时频平移的窗函数,也称为Gabor原子。
另一种等价定义是Gabor变换形式:
Gwf(t,ω)=∫−∞∞f(τ)w(τ−t)‾e−iω(τ−t) dτG_w f(t, \omega) = \int_{-\infty}^{\infty} f(\tau) \overline{w(\tau - t)} e^{-i\omega(\tau-t)} \, d\tauGwf(t,ω)=∫−∞∞f(τ)w(τ−t)e−iω(τ−t)dτ
两种定义通过相位因子 e−iωte^{-i\omega t}e−iωt 相关联:
Vwf(t,ω)=e−iωtGwf(t,ω)V_w f(t, \omega) = e^{-i\omega t} G_w f(t, \omega)Vwf(t,ω)=e−iωtGwf(t,ω)
有效的窗函数应满足以下条件:
1. 高斯窗函数
wσ(t)=(1πσ2)1/4exp(−t22σ2)w_{\sigma}(t) = \left(\frac{1}{\pi\sigma^2}\right)^{1/4} \exp\left(-\frac{t^2}{2\sigma^2}\right)wσ(t)=(πσ21)1/4exp(−2σ2t2)
高斯窗是唯一同时在时域和频域都达到Heisenberg不确定性下界的窗函数。
2. Kaiser窗函数
wβ(t)=I0(β1−(2t/T)2)I0(β),∣t∣≤T/2w_{\beta}(t) = \frac{I_0\left(\beta\sqrt{1-(2t/T)^2}\right)}{I_0(\beta)}, \quad |t| \leq T/2wβ(t)=I0(β)I0(β1−(2t/T)2),∣t∣≤T/2
其中 I0(⋅)I_0(\cdot)I0(⋅) 为第一类零阶修正贝塞尔函数,β\betaβ 为形状参数。
3. Tukey窗函数
wα(t)={12[1+cos(2παT(∣t∣−αT2))]αT2≤∣t∣≤T21∣t∣<αT20∣t∣>T2w_{\alpha}(t) = \begin{cases} \frac{1}{2}\left[1 + \cos\left(\frac{2\pi}{\alpha T}\left(|t| - \frac{\alpha T}{2}\right)\right)\right] & \frac{\alpha T}{2} \leq |t| \leq \frac{T}{2} \\ 1 & |t| < \frac{\alpha T}{2} \\ 0 & |t| > \frac{T}{2} \end{cases}wα(t)=⎩ ⎨ ⎧21[1+cos(αT2π(∣t∣−2αT))]102αT≤∣t∣≤2T∣t∣<2αT∣t∣>2T
对于任意函数 f(t)∈L2(R)f(t) \in L^2(\mathbb{R})f(t)∈L2(R),其时间和频率的有效宽度满足:
Δtf⋅Δωf≥12\Delta_t f \cdot \Delta_\omega f \geq \frac{1}{2}Δtf⋅Δωf≥21
其中:
Δtf=∫t2∣f(t)∣2dt∫∣f(t)∣2dt−(∫t∣f(t)∣2dt∫∣f(t)∣2dt)2\Delta_t f = \sqrt{\frac{\int t^2 |f(t)|^2 dt}{\int |f(t)|^2 dt} - \left(\frac{\int t |f(t)|^2 dt}{\int |f(t)|^2 dt}\right)^2}Δtf=∫∣f(t)∣2dt∫t2∣f(t)∣2dt−(∫∣f(t)∣2dt∫t∣f(t)∣2dt)2
Δωf=∫ω2∣f^(ω)∣2dω∫∣f^(ω)∣2dω−(∫ω∣f^(ω)∣2dω∫∣f^(ω)∣2dω)2\Delta_\omega f = \sqrt{\frac{\int \omega^2 |\hat{f}(\omega)|^2 d\omega}{\int |\hat{f}(\omega)|^2 d\omega} - \left(\frac{\int \omega |\hat{f}(\omega)|^2 d\omega}{\int |\hat{f}(\omega)|^2 d\omega}\right)^2}Δωf=∫∣f^(ω)∣2dω∫ω2∣f^(ω)∣2dω−(∫∣f^(ω)∣2dω∫ω∣f^(ω)∣2dω)2
对于给定窗函数 w(t)w(t)w(t),STFT的时频分辨率由窗函数的时频特性决定:
分辨率矩形的面积为:
A=Δtw⋅Δωw≥12A = \Delta_t w \cdot \Delta_\omega w \geq \frac{1}{2}A=Δtw⋅Δωw≥21
设连续信号 f(t)f(t)f(t) 的采样版本为 f[n]=f(nTs)f[n] = f(nT_s)f[n]=f(nTs),其中 TsT_sTs 为采样间隔。根据Nyquist采样定理,为避免混叠,采样频率应满足:
fs=1Ts≥2fmaxf_s = \frac{1}{T_s} \geq 2f_{\max}fs=Ts1≥2fmax
其中 fmaxf_{\max}fmax 为信号的最高频率成分。
离散短时傅里叶变换定义为:
X[m,k]=∑n=0N−1x[n]w[n−mH]e−j2πkn/NX[m, k] = \sum_{n=0}^{N-1} x[n] w[n-mH] e^{-j2\pi kn/N}X[m,k]=n=0∑N−1x[n]w[n−mH]e−j2πkn/N
其中:
为保证信号的连续性和减少边界效应,通常采用重叠加窗技术:
重叠率=N−HN×100%\text{重叠率} = \frac{N - H}{N} \times 100\%重叠率=NN−H×100%
常用的重叠率为50%、75%或87.5%。
算法3.1: 离散STFT计算算法
输入: 信号 x[n], 窗函数 w[n], 帧移 H, FFT长度 N
输出: 时频矩阵 X[m,k]
1. 初始化: M = floor((length(x)-N)/H) + 1
2. for m = 0 to M-1:
3. 提取信号帧: x_frame = x[mH : mH+N-1]
4. 应用窗函数: x_windowed = x_frame .* w
5. 零填充(如需要): x_padded = [x_windowed, zeros]
6. 计算FFT: X[m,:] = FFT(x_padded)
7. 返回 X[m,k]
对于长度为 LLL 的信号,窗长为 NNN,帧移为 HHH:
逆STFT可通过重叠相加法实现:
x^[n]=∑mw[n−mH]⋅IFFT{X[m,k]}[n−mH]∑mw2[n−mH]\hat{x}[n] = \frac{\sum_{m} w[n-mH] \cdot \text{IFFT}\{X[m,k]\}[n-mH]}{\sum_{m} w^2[n-mH]}x^[n]=∑mw2[n−mH]∑mw[n−mH]⋅IFFT{X[m,k]}[n−mH]
为保证完美重构,窗函数和帧移必须满足:
∑m=−∞∞w[n−mH]=C∀n\sum_{m=-\infty}^{\infty} w[n-mH] = C \quad \forall nm=−∞∑∞w[n−mH]=C∀n
其中 CCC 为常数。常用的窗函数(如Hann窗)在50%重叠时满足此条件。
1. 主瓣宽度
窗函数频谱的主瓣宽度决定频率分辨率:
BWmain=4πNBW_{\text{main}} = \frac{4\pi}{N}BWmain=N4π
2. 旁瓣抑制比
最大旁瓣与主瓣的比值:
PSR=20log10(∣W(ωmain)∣∣W(ωsidelobe)max∣)PSR = 20\log_{10}\left(\frac{|W(\omega_{\text{main}})|}{|W(\omega_{\text{sidelobe}})_{\max}|}\right)PSR=20log10(∣W(ωsidelobe)max∣∣W(ωmain)∣)
3. 相干增益与处理增益
多目标优化问题:
minw{α⋅BWmain+β⋅PSR−1+γ⋅PG−1}\min_{w} \left\{ \alpha \cdot BW_{\text{main}} + \beta \cdot PSR^{-1} + \gamma \cdot PG^{-1} \right\}wmin{α⋅BWmain+β⋅PSR−1+γ⋅PG−1}
约束条件:
基于信号局部平稳性的窗长自适应算法:
Lopt(t)=argminL{σbias2(L)σvariance2(L)}L_{\text{opt}}(t) = \arg\min_L \left\{ \frac{\sigma_{\text{bias}}^2(L)}{\sigma_{\text{variance}}^2(L)} \right\}Lopt(t)=argLmin{σvariance2(L)σbias2(L)}
其中偏差-方差权衡通过交叉验证确定。
对于强非平稳信号,可采用时变窗函数:
wt(τ)=w(τ)⋅g(t,τ)w_t(\tau) = w(\tau) \cdot g(t, \tau)wt(τ)=w(τ)⋅g(t,τ)
其中 g(t,τ)g(t, \tau)g(t,τ) 为时变调制函数。
STFT算子 VwV_wVw 是线性的:
Vw(αf+βg)=αVwf+βVwgV_w(\alpha f + \beta g) = \alpha V_w f + \beta V_w gVw(αf+βg)=αVwf+βVwg
Vw(Tτf)(t,ω)=Vwf(t−τ,ω)V_w(T_\tau f)(t, \omega) = V_w f(t - \tau, \omega)Vw(Tτf)(t,ω)=Vwf(t−τ,ω)
其中 Tτf(t)=f(t−τ)T_\tau f(t) = f(t - \tau)Tτf(t)=f(t−τ) 为时移算子。
Vw(MΩf)(t,ω)=Vwf(t,ω−Ω)V_w(M_\Omega f)(t, \omega) = V_w f(t, \omega - \Omega)Vw(MΩf)(t,ω)=Vwf(t,ω−Ω)
其中 MΩf(t)=eiΩtf(t)M_\Omega f(t) = e^{i\Omega t} f(t)MΩf(t)=eiΩtf(t) 为频移算子。
∫−∞∞∫−∞∞∣Vwf(t,ω)∣2 dt dω=∥w∥22∥f∥22\int_{-\infty}^{\infty} \int_{-\infty}^{\infty} |V_w f(t, \omega)|^2 \, dt \, d\omega = \|w\|_2^2 \|f\|_2^2∫−∞∞∫−∞∞∣Vwf(t,ω)∣2dtdω=∥w∥22∥f∥22
STFT具有再现核希尔伯特空间结构,其再现核为:
Kw((t,ω),(t′,ω′))=⟨wt,ω,wt′,ω′⟩K_{w}((t, \omega), (t', \omega')) = \langle w_{t,\omega}, w_{t',\omega'} \rangleKw((t,ω),(t′,ω′))=⟨wt,ω,wt′,ω′⟩
对于线性调频信号 s(t)=ei(ω0t+αt2/2)s(t) = e^{i(\omega_0 t + \alpha t^2/2)}s(t)=ei(ω0t+αt2/2),STFT的瞬时频率估计偏差为:
Δωbias=α⋅∫t2∣w(t)∣2dt∫∣w(t)∣2dt\Delta\omega_{\text{bias}} = \alpha \cdot \frac{\int t^2 |w(t)|^2 dt}{\int |w(t)|^2 dt}Δωbias=α⋅∫∣w(t)∣2dt∫t2∣w(t)∣2dt
两个频率成分 ω1\omega_1ω1 和 ω2\omega_2ω2 的可分辨条件:
∣ω1−ω2∣≥ΔωwSNR|\omega_1 - \omega_2| \geq \frac{\Delta_\omega w}{\sqrt{SNR}}∣ω1−ω2∣≥SNRΔωw
其中 SNRSNRSNR 为信噪比。
在加性白高斯噪声环境下,STFT系数的方差为:
Var[Vw(f+n)(t,ω)]=σn2∥w∥22\text{Var}[V_w(f + n)(t, \omega)] = \sigma_n^2 \|w\|_2^2Var[Vw(f+n)(t,ω)]=σn2∥w∥22
窗函数的处理增益提供的SNR改善为:
SNRimprovement=10log10(PG) dBSNR_{\text{improvement}} = 10\log_{10}(PG) \text{ dB}SNRimprovement=10log10(PG) dB
存储时频矩阵所需内存:
Memory=M×K×sizeof(complex) bytes\text{Memory} = M \times K \times \text{sizeof(complex)} \text{ bytes}Memory=M×K×sizeof(complex) bytes
其中 MMM 为时间帧数,KKK 为频率箱数。
实时处理的延迟约束:
Tprocessing
其中 TprocessingT_{\text{processing}}Tprocessing 为单帧处理时间。
在语音识别系统中,STFT用于提取梅尔频率倒谱系数(MFCC):
基于STFT的谱减法:
S^[m,k]=(1−ασ^n2[k]∣Y[m,k]∣2)Y[m,k]\hat{S}[m,k] = \left(1 - \alpha \frac{\hat{\sigma}_n^2[k]}{|Y[m,k]|^2}\right) Y[m,k]S^[m,k]=(1−α∣Y[m,k]∣2σ^n2[k])Y[m,k]
其中 Y[m,k]Y[m,k]Y[m,k] 为含噪语音的STFT,σ^n2[k]\hat{\sigma}_n^2[k]σ^n2[k] 为噪声功率谱估计。
脑电信号的频带功率计算:
心率变异性(HRV)的频域分析:
对于线性调频(LFM)信号:
s(t)=Aexp(j2π(f0t+μt22))s(t) = A \exp\left(j2\pi\left(f_0 t + \frac{\mu t^2}{2}\right)\right)s(t)=Aexp(j2π(f0t+2μt2))
STFT的峰值轨迹为:
fpeak(t)=f0+μtf_{\text{peak}}(t) = f_0 + \mu tfpeak(t)=f0+μt
运动目标的多普勒频移:
fd=2vrfccf_d = \frac{2v_r f_c}{c}fd=c2vrfc
其中 vrv_rvr 为径向速度,fcf_cfc 为载频,ccc 为光速。
基于STFT的基频估计:
音色描述子提取:
方法 | 时间复杂度 | 空间复杂度 | 时间分辨率 | 频率分辨率 | 适用场景 |
---|---|---|---|---|---|
FFT | O(NlogN)O(N\log N)O(NlogN) | O(N)O(N)O(N) | 无 | fs/Nf_s/Nfs/N | 平稳信号 |
STFT | O(MNlogN)O(MN\log N)O(MNlogN) | O(MN)O(MN)O(MN) | Δtw\Delta t_wΔtw | Δfw\Delta f_wΔfw | 短时平稳信号 |
CWT | O(MN2)O(MN^2)O(MN2) | O(MN)O(MN)O(MN) | 尺度自适应 | 尺度自适应 | 多尺度信号 |
WVD | O(N2)O(N^2)O(N2) | O(N2)O(N^2)O(N2) | 理论最优 | 理论最优 | 单分量信号 |
STFT的优势:
STFT的局限:
以下示例代码演示如何使用Python中的librosa
和matplotlib
库进行STFT计算,并绘制信号的时频图(频谱图)。
import numpy as np
import matplotlib.pyplot as plt
import librosa
import librosa.display
sr = 8000 # 采样率8000Hz
t = np.linspace(0, 1, sr, endpoint=False)
f1, f2 = 300, 1500 # 两个频率成分300Hz和1500Hz
signal = 0.5 * np.sin(2 * np.pi * f1 * t) + 0.5 * np.sin(2 * np.pi * f2 * t)
# 添加噪声
noise = np.random.normal(0, 0.3, signal.shape)
noisy_signal = signal + noise
# STFT参数
n_fft = 1024 # FFT点数
hop_length = 256 # 帧移
window = 'hann' # 窗函数
stft_result = librosa.stft(noisy_signal, n_fft=n_fft, hop_length=hop_length, window=window)
stft_db = librosa.amplitude_to_db(np.abs(stft_result), ref=np.max)
plt.figure(figsize=(14, 6))
librosa.display.specshow(stft_db, sr=sr, hop_length=hop_length, x_axis='time', y_axis='hz', cmap='magma')
plt.colorbar(format='%+2.0f dB')
plt.title('信号的时频图(STFT)')
plt.xlabel('时间 (秒)')
plt.ylabel('频率 (Hz)')
plt.tight_layout()
plt.show()