视频加载失败

窗函数法设计FIR滤波器

902 字
5 分钟
窗函数法设计FIR滤波器
窗函数法设计FIR滤波器

信号选取#

设被采样信号连续时间函数为 f(t) = 2sin(2pif1t) + 10sin(2pif2t) + 5sin(2pif3t) 其中, f1 = 100;
f2 = 400;
f3 = 800;

依据采样定理,设
fs = 2400;
Ts = 1/fs;

连续时间t和采样时间的关系可以表示为
t = n*Ts
其中n为序列的下标

取观察时间T = 0.1s;

使用matlab生成离散时间信号序列#

% 被采样信号设为f(t) = 2*sin(2*pi*f1*t) + 10*sin(2*pi*f2*t) + 5*sin(2*pi*f3*t)
f1 = 100;
f2 = 400;
f3 = 800;
fs = 2400;
Ts = 1/fs;
% 观察时间
T = 0.1;
% 序列索引
n = 0:round(T/Ts);
% 连续时间t和采样时刻的关系
t = n*Ts;
% 序列
x = 2*sin(2*pi*f1*t) + 10*sin(2*pi*f2*t) + 5*sin(2*pi*f3*t);
N = length(x);

标准DFT函数#

function X_w = DFT(x,N)
for k = 0 : N - 1
S = 0;
for n = 0 : N - 1
S = S + x(n+1) * exp(-1j*(2*pi*k*n/N));
end
X_w(k+1) = S;
% X_clean = round(real(X_w), 12) + 1i*round(imag(X_w), 12);
end
end

观察信号的频谱#

X_w = DFT(x, length(x));
k = 0:length(X_w)-1;
% 绘图
figure;
subplot(2,1,1);
stem(n, x, 'filled');
xlabel('n');
ylabel('x[n]');
title('时域序列');
grid on;
subplot(2,1,2);
stem(k, abs(X_w), 'filled');
xlabel('k');
ylabel('|X[k]|');
title('DFT幅度谱');
grid on;

可以得出:

alt text
alt text

现在的目标就是抑制频率为800hz的信号成分
可以设理想滤波器的通带截至频率为wp = 2 * pi * 500hz,阻带频率为ws = 2 * pi * 600hz

理想滤波器公式:

alt text
alt text

注意,公式中的角频率是不是Hz为单位,而是离散时间角频率,即rad/sample

连续时间信号x(t)=cos⁡(2πft)x(t)=\cos(2\pi f t)
采样后:t=nTs=nfst=nT_s=\frac{n}{f_s}
所以:

x[n]=cos⁡(2πfnfs)=cos⁡(ωn)x[n] =\cos\left(2\pi f\frac{n}{f_s}\right) =\cos(\omega n)

因此不妨直接设
wp = wp = 2 * pi * 500 / fs
ws = 2 * pi * 600 / fs

则有截止频率
wc = (ws+wp) * 0.5;

如下matlab代码的理想滤波器实现

ws = 2*pi*500/fs;
wp = 2*pi*600/fs;
wc = (ws+wp) * 0.5;
alpha = (N - 1) / 2;
% 理想滤波器
% hd = sin(wc * (n - alpha)) ./ (pi * (n - alpha));
for m = 0 : N - 1
if (n(m + 1) - alpha) ~= 0
hd(m + 1) = sin(wc * (n(m + 1) - alpha)) / (pi * (n(m + 1) - alpha));
else
hd(m + 1) = wc / pi;
end
end

alt text
alt text
(n(m + 1) - alpha) ~= 0表示公式中n - alpha不为0的时候,当n - alpha = 0时,可求得 hd = wc / pi

选择窗函数—Hann 窗为例#

% 窗函数
w = 0.5 * (1 - cos(2*pi*n / (N - 1)));

将理想滤波器与窗函数在时序相乘对理想滤波器进行截断,得到滤波器系数

% 滤波器
h = hd .* w;

查看滤波器的频域响应是否符合预期

Hw = DFT(h,length(h));
wk = 0 : length(h) - 1;
figure;
subplot(1,1,1);
stem(wk, abs(Hw), 'filled');
xlabel('wk');
ylabel('|hw|');
title('滤波器');
grid on;

alt text
alt text

由于DFT的周期性质,因此DTF图像上后部分有一段重复的图像。

得到滤波后的信号#

要得到滤波后的信号则直接将信号和滤波器进行卷积

x_f = conv(x, h); % 卷积之后长度会变化
n_xf = 0 : length(x_f) - 1;

注意卷积之后长度会变化,不再是N
再对滤波后的信号进行DTF分析

Xf_w = DTF(x_f, length(x_f));
k_xf = 0 : length(Xf_w) - 1;

最后绘制图像

figure;
subplot(3,1,1);
stem(wk, abs(Hw), 'filled');
xlabel('wk');
ylabel('|hw|');
title('滤波器');
grid on;
subplot(3,1,2);
stem(n_xf, x_f, 'filled');
xlabel('n_xf');
ylabel('x_f');
title('滤波后信号');
grid on;
subplot(3,1,3);
stem(k_xf, abs(Xf_w), 'filled');
xlabel('k_xf');
ylabel('|Xf_w|');
title('滤波后频谱');
grid on;

alt text
alt text

由于群延迟的存在,因此滤波后的时域信号产生了延迟,在图像上表现为往后延迟了,前100+个采样点的值在0附近。
由: ϕ(ω)=−N−12ω\phi(\omega)=-\frac{N-1}{2}\omega
可得群延迟:
τg(ω)=−dϕ(ω)dω=N−12\tau_g(\omega)=-\frac{d\phi(\omega)}{d\omega}=\frac{N-1}{2}
因此所有通过的频率分量大约都延迟:
N−12\frac{N-1}{2}
个采样点,滤波后波形整体向右移动。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

窗函数法设计FIR滤波器
https://chachaprj.top/posts/2026-10-12/
作者
ChaCha
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
ChaCha
Pain Equals Gain
公告
欢迎来到我的博客!
分类
标签
最新动态
站点统计
文章
15
分类
7
标签
19
总字数
21,598
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录