IIR滤波器Matlab设计与实现,完整实例

IIR 滤波器是数字信号处理常用滤波器,相同性能要求下,阶数比 FIR 小很多,计算量更小。Matlab 设计 IIR 特别方便,不用自己算系数,几行代码就搞定,我给完整实例,拿来就能用。
基本概念
IIR 就是无限冲激响应滤波器,特点是有反馈,相同指标需要阶数比 FIR 小很多,缺点就是没有线性相位。对相位要求不高的场景,比如音频预处理、信号检测,IIR 完全够用。
常用几种:
- 巴特沃斯:通带阻带都平坦,最常用
- 切比雪夫:通带带波纹,过渡带更窄
- 椭圆:过渡带最窄,代价是通带阻带都有波纹
Matlab 都有现成函数,直接调用就行。
设计实例:8阶巴特沃斯低通
我们设计采样率 1000Hz,截止 50Hz 的低通:
算系数
fs = 1000; % 采样率 Hz
fc = 50; % 截止频率 Hz
n = 8; % 阶数
[b,a] = butter(n, fc/(fs/2));
butter 第一个参数阶数,第二个是归一化截止,除以 fs/2 归一到 0-1,输出 b 分子 a 分母,系数算好了。
检查频率响应
算完画出来看看对不对:
freqz(b,a,1024,fs);
直接出幅频相频曲线,看看 50Hz 是不是衰减 3dB,阻带衰减够不够,一眼就能看出对不对。
滤波
系数对了直接滤波:
% x 是你的原始信号
y = filtfilt(b,a,x); % 零相位滤波
% 或者 y = filter(b,a,x); 实时滤波用这个
推荐用 filtfilt,零相位,滤波完信号不偏移,相位还是对的,就是算两遍,速度慢一点,非实时无所谓。实时处理只能用 filter。
其他类型滤波器设计
改几个参数就好了,很简单。
高通滤波器
还是 8 阶,截止 50Hz 高通:
[b,a] = butter(n, fc/(fs/2), 'high');
最后加个 'high' 参数就完事。
带通滤波器
通带 50 到 200Hz:
fc = [50 200];
[b,a] = butter(n, fc/(fs/2), 'bandpass');
截止频率给两个数,加 'bandpass' 就好了。
带阻滤波器
滤 50Hz 工频干扰,带阻 45 到 55Hz:
fc = [45 55];
[b,a] = butter(n, fc/(fs/2), 'stop');
加 'stop',直接搞定,工频干扰用这个特别方便。
切比雪夫和椭圆设计
需要更窄过渡带,巴特沃斯阶数不够,就用这两个:
切比雪夫 I 型例子,8 阶低通,通带波纹 3dB:
Rp = 3; % 通带最大波纹 dB
[n, Wn] = cheb1ord(fc/(fs/2), 100/(fs/2), Rp, 50);
[b,a] = cheby1(n, Rp, Wn);
cheb1ord 自动算满足指标最小阶数,不用你自己猜,省心。
椭圆滤波器:
Rp = 3; % 通带波纹 dB
Rs = 50; % 阻带最小衰减 dB
[n, Wn] = ellipord(fc/(fs/2), 100/(fs/2), Rp, Rs);
[b,a] = ellip(n, Rp, Rs, Wn);
椭圆得到同样过渡带,阶数比巴特沃斯小一半都有可能,省计算量。
完整实例:滤除 50Hz 工频干扰
实际信号经常沾 50Hz 工频干扰,我们滤一下:
fs = 1000;
t = 0:1/fs:1;
x = sin(2*pi*10*t) + 0.5*sin(2*pi*50*t); % 10Hz 信号加 50Hz 干扰
% 设计 50Hz 带阻
n = 4;
fc = [45 55];
[b,a] = butter(n, fc/(fs/2), 'stop');
% 滤波
y = filtfilt(b,a,x);
% 画图
subplot(2,1,1);
plot(t,x); title('原始信号');
subplot(2,1,2);
plot(t,y); title('滤波后信号');
跑完看结果,50Hz 干扰基本没了,10Hz 信号几乎没变,完美。
怎么选阶数
阶数越高,过渡带越陡,但是计算量大,还容易不稳定,阶数太高可能振荡发散。
一般你给通带阻带要求,用 buttord cheb1ord ellipord 自动算最小需要的阶数,不用你自己试,直接用结果就行。
例子:要求通带 0-50Hz,波纹 3dB,阻带 80Hz 开始衰减 40dB:
Wp = 50/(fs/2); Ws = 80/(fs/2);
[n, Wn] = buttord(Wp, Ws, 3, 40);
[b,a] = butter(n,Wn);
自动出最小阶数,省得你试半天。
常见问题
滤波完溢出
系数对一般不会,真溢出降阶就行,肯定阶数太高了,检查输入范围对不对。
相位不对
filter 本身就有相位偏移,要零相位用 filtfilt,非实时都推荐这个。
结果发散
阶数太高不稳定,降阶就行,一般 10 阶以内都稳定,Matlab 算系数已经优化过了。
Matlab 设计 IIR 真的简单,选对类型,算完系数滤波三步完事,巴特沃斯最常用,没特殊要求就用它,要更窄过渡带再试切比雪夫或者椭圆。碰到工频干扰直接照着实例改参数就能用。

浙公网安备 33010602011771号