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 真的简单,选对类型,算完系数滤波三步完事,巴特沃斯最常用,没特殊要求就用它,要更窄过渡带再试切比雪夫或者椭圆。碰到工频干扰直接照着实例改参数就能用。

posted @ 2026-05-08 07:49  codinglife66  阅读(58)  评论(0)    收藏  举报