四种常见窗函数(矩形窗、汉宁窗、汉明窗、布莱克曼窗)的作用、公式及C++代码实现,适用于信号处理场景(如FFT、滤波器设计等)。
1. 矩形窗(Rectangular Window)
作用:
-
最简单的窗函数,无任何加权,直接截断信号。
-
优点:主瓣宽度最窄(频率分辨率最高)。
-
缺点:旁瓣衰减差(-13 dB),频谱泄漏严重。
公式:
C++代码:
#include <vector>
std::vector<double> rectangularWindow(int N) {
return std::vector<double>(N, 1.0); // 所有系数为1
}
2. 汉宁窗(Hanning Window)
作用:
-
通过余弦加权减少频谱泄漏,旁瓣衰减-31.5 dB。
-
平衡频率分辨率和旁瓣抑制,适用于大多数频谱分析场景。
公式:
C++代码:
#include <vector>
#include <cmath>
std::vector<double> hanningWindow(int N) {
std::vector<double> window(N);
for (int n = 0; n < N; ++n) {
window[n] = 0.5 * (1 - cos(2 * M_PI * n / (N - 1)));
}
return window;
}
3. 汉明窗(Hamming Window)
作用:
-
优化汉宁窗的旁瓣衰减(-42 dB),但主瓣宽度相同。
-
适用于需要更强旁瓣抑制的场景(如滤波器设计)。
公式:
C++代码:
std::vector<double> hammingWindow(int N) {
std::vector<double> window(N);
for (int n = 0; n < N; ++n) {
window[n] = 0.54 - 0.46 * cos(2 * M_PI * n / (N - 1));
}
return window;
}
4. 布莱克曼窗(Blackman Window)
作用:
-
进一步抑制旁瓣(-58 dB),但主瓣最宽(频率分辨率最低)。
-
适用于对频谱泄漏极度敏感的场景。
公式:
C++代码:
std::vector<double> blackmanWindow(int N) {
std::vector<double> window(N);
for (int n = 0; n < N; ++n) {
window[n] = 0.42 - 0.5 * cos(2 * M_PI * n / (N - 1))
+ 0.08 * cos(4 * M_PI * n / (N - 1));
}
return window;
}
5. 窗函数特性对比表
窗函数 | 主瓣宽度 | 旁瓣衰减(dB) | 适用场景 |
---|---|---|---|
矩形窗 | 1×(最窄) | -13 | 高频率分辨率,可接受泄漏 |
汉宁窗 | 2× | -31.5 | 通用频谱分析 |
汉明窗 | 2× | -42 | 强旁瓣抑制(如通信系统) |
布莱克曼窗 | 6×(最宽) | -58 | 极低泄漏需求(如精密测量) |
6. 使用示例(C++)
cpp
#include <iostream>
#include "windows.h" // 假设上述代码保存在此头文件
int main() {
int N = 64;
auto hanning = hanningWindow(N);
// 打印前5个系数
for (int i = 0; i < 5; ++i) {
std::cout << "Hanning[" << i << "] = " << hanning[i] << std::endl;
}
return 0;
}
注意事项:
-
代码中
M_PI
需包含<cmath>
头文件(或自定义#define M_PI 3.14159265358979323846
)。 -
窗函数系数通常对称,实际应用中可能无需计算全部点(利用对称性优化)。