【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现

之前的两篇文章分别介绍了FIR和IIR的基础理论,这一篇我们将介绍其在MATLAB中的具体实现方法。

一、MATLAB中滤波器的设计方法

MATLAB为滤波设置了种工具,比如图形化的设计工具filterDesginer、根据差分方程直接设计滤波器的filter函数、根据滤波目的进行设计的lowpass函数、highpass函数等等。

不过我最终选用了designfilt函数进行FIR、IIR滤波器设计实现。因为该函数兼具了方法的全面性统一性,而且相对于图形界面,纯代码的形式在很多场景下也更便于调用。

二、使用designfilt函数进行滤波

这里我们举一个例子来说明designfilt函数的用法。

准备滤波的对象数据如下,我们对该数据进行低通滤波:

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第1张图片

滤波前数据

1.导入数据。

我们将该数据命名为data,在程序中使用如下代码进行导入:

%% 1.导入数据
load data.mat

此步骤也可以是导入其他格式的数据文件,比如Excel、csv、txt、一些音频格式等等,数据导入视频教程可以参考这里:MATLAB数据导入教程 – 二号城堡

也可以不导入数据而是使用仿真数据,那么此处就对应改成数据仿真的计算公式。

2.参数设置

下面我们设计一个FIR低通滤波器,所以type设置成了“lowpassfir”,此外根据滤波器类型和设计方法的不同,可以选择:'lowpassfir' 、 'lowpassiir' 、'highpassfir'、 'highpassiir'、 'bandpassfir' 、'bandpassiir''bandstopfir''bandstopiir' 。

在这个例子里边我们需要指定四个参数,分别是滤波器阶数、低通截止频率、数据采样频率、设计方法。

type = 'lowpassfir';
order = 50;      %滤波器阶数
CutoffFrequency = 75;  %低通截止频率
Fs = 500;  %数据采样频率
DesignMethod = 'window'  %设计方法

3.实现滤波并画图

下边这行代码是将上述参数导入designfilt函数,得到设计完成的滤波器d。

d =designfilt(type,'FilterOrder',order,...'CutoffFrequency',Fst,'SampleRate',Fs,'DesignMethod',DesignMethod);

然后调用filter函数,实现滤波,filter入口参数为滤波器d和待滤波数据data。

xf = filter(d,data);  %xf为滤波后数据

此时绘制一下滤波前数据和滤波后数据的对比图:

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第2张图片

可以看到滤波结果是有相位延迟的,对于相位延迟,在之前的文章中也介绍过。由于FIR滤波的相位延迟是线性的,可以通过平移进行延迟补偿(不用担心,IIR滤波器也可以相位补偿):

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第3张图片

相位补偿后的结果

四、关于designfilt函数的其他规范集

这里要提到一个“规范集”的概念,可以看一下下图:

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第4张图片

lowpassfir的规范集

上图是lowpassfir的规范集,对于其他七种方法,都有这样一张规范集列表。所谓的“规范集”简单来说就是designfilt函数支持不同的滤波器设计方法(这里的设计方法不是指FIR或者IIR,而是更加细分的“window、butter”等等),而在不同的设计方法中,需要输入的各种参数都会有所不同。而上表就是列出在不同的设计方法下需要设置哪些参数。

我们在上边程序中用到的规范集是下边红框框出来的这一行:

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第5张图片

如果在你的研究需求中,要使用其他规范集,就需要参考到这张表了。

三、代码的傻瓜化封装——一行代码实现FIR/IIR滤波

通过上述方法结合官方教程文档,我们可以实现滤波器的设计,但是对于新手来说多少还是有一些门槛的,而且对于很多应用场景,我们并不需要考虑那么多种规范集形式。

有没有一种更简便易用,兼顾专业性,最好还可以多功能分析画图的实现方法呢?

现在有了——笔者按照专栏以往的的代码风格,对FIR、IIR算法进行了二次封装,实现了“一行代码”完成滤波的效果。我将封装后的函数命名为funFirIirFliter

比如还是对于上边的例子,只需要像下边这样设置参数并调用funFirIirFliter函数:

resp = 'lowpassfir';  %选择滤波器类型
option.order = 50;    %设置滤波器阶数
option.CutoffFrequency = 75;  %设置滤波器截止频率
option.Fs = 500;              %设置信号采样频率
compFlag = 'on';     %compFlag:是否进行延迟补偿,'on'为开启补偿,'off'为关闭补偿。      
%% 3.调用funFirIirFliter实现滤波
dataOut = funFirIirFliter(data,resp,option,compFlag);  

就可以得到如下结果:

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第6张图片

图1. 滤波器响应图

【滤波专题-第5篇】FIR、IIR滤波器设计及MATLAB实现_第7张图片

图2. 滤波效果图

图1是设计得到的滤波器响应图;图2是滤波效果图,其中包括滤波前信号及频谱、滤波后信号及频谱、滤波前后信号对比图(可以用于比较相位滞后情况)。

也就是说只要向funFirIirFliter函数导入待分析的数据、选择滤波器类型(如'firlowpass'等)、进行option相关参数设置(对于不同的滤波器类型设置大概3-4个参数),还可以选择是否进行相位补偿(通过设置compFlag参数为'on'或'off')。然后调用一行“funFirIirFliter(data,resp,option,compFlag);”,就可以实现上述所有功能了。

对于funFirIirFliter函数更详细的注释说明如下:

function [dataOut,d] = funFirIirFliter(data,resp,option,compFlag)
% 进行FIR或者IIR滤波,可以实现滤波器设计、滤波、画图
% 如需对下述代码进行二次开发,可参考此官方帮助文档:https://ww2.mathworks.cn/help/signal/ref/designfilt.html?s_tid=doc_ta
% 输入:
% data:待滤波数据
% resp:滤波器响应类型和滤波类型,具体包含:
%       -'lowpassfir'      FIR低通滤波器,采用'window'设计方法对应的规范集,需要设置的参数包括:
%                          - option.order 滤波器阶数
%                          - option.CutoffFrequency 滤波器截止频率
%                          - option.Fs 采样频率
%       -'lowpassiir'      IIR低通滤波器,采用最小阶设计对应的规范集
%                          - option.Fs 采样频率
%                          - option.PassbandFrequency     通带频率
%                          - option.StopbandFrequency     阻带频率
%                          - option.DesignMethod     设计方法,选项: 'butter'、'cheby1'、'cheby2'、'ellip'
%       -'highpassfir'      FIR高通滤波器,采用'window'设计方法对应的规范集,需要设置的参数包括:
%                          - option.order 滤波器阶数
%                          - option.CutoffFrequency 滤波器截止频率
%                          - option.Fs 采样频率
%       -'highpassiir'     IIR高通滤波器,采用最小阶设计对应的规范集
%                          - option.Fs 采样频率
%                          - option.PassbandFrequency     通带频率
%                          - option.StopbandFrequency     阻带频率
%                          - option.DesignMethod     设计方法,选项: 'butter'、'cheby1'、'cheby2'、'ellip'
%       -'bandpassfir'     FIR带通滤波器,采用'window'设计方法对应的规范集,需要设置的参数包括:
%                          - option.order 滤波器阶数
%                          - option.CutoffFrequency1,... %通带起始频率
%                          - option.CutoffFrequency2,... %通带结束频率
%                          - option.Fs 采样频率
%       -'bandpassiir'     IIR带通滤波器,采用最小阶设计对应的规范集
%                          - option.Fs 采样频率
%                          - option.StopbandFrequency1, ...    % 阻带起始频率
%                          - option.PassbandFrequency1, ...    % 通带起始频率
%                          - option.PassbandFrequency2, ...    % 阻带截止频率
%                          - option.StopbandFrequency2, ...    % 通带截止频率
%                          - option.DesignMethod     设计方法,选项: 'butter'、'cheby1'、'cheby2'、'ellip'
%       -'bandstopfir'     FIR带阻滤波器,采用'window'设计方法对应的规范集,需要设置的参数包括:
%                          - option.order 滤波器阶数
%                          - option.CutoffFrequency1,... %通带起始频率
%                          - option.CutoffFrequency2,... %通带结束频率
%                          - option.Fs 采样频率
%       -'bandstopiir'     IIR带阻滤波器
%                          - option.order 滤波器阶数
%                          - option.CutoffFrequency1,... %通带起始频率
%                          - option.CutoffFrequency2,... %通带结束频率
%                          - option.Fs 采样频率
%
% compFlag:是否进行延迟补偿,'on'为开启补偿,'off'为关闭补偿。-对于fir方法,开启补偿会使得滤波后的数据变短,这是由于通过时移对其数据导致的,会删除最后 delay 个采样点
%            
% 输出:
% dataOut:滤波后数据
% d:设计好的滤波器

上述函数选择了每种滤波器类型较为常用的规范集,同学们可以不用再选择恐惧症,而是把精力更多放在应用效果上。对于有进阶需求的同学,还可以在封装函数里进行二次开发,自行换用其他规范集,可以说比较灵活易用了。

需要上边这个函数文件以及测试代码的同学,可以在下述链接获取:

FIR、IIR滤波算法 | 工具箱文档

end.关于滤波专题

目前计划要讲到的包括:

-1.FIR有限冲激响应、IIR无限冲激响应数字滤波算法的理论讲解、滤波器设计方法和MATLAB代码实现
-2.滤波器滤波效果的评价指标
-3.“类EMD”方法(即包括EMD、EEMD、CEEMD、VMD等一系列方法)的滤波算法讲解与实现
-4.“类EMD”方法与ICA结合的滤波算法讲解与实现
-5.小波阈值滤波方法讲解与实现
-6.卡尔曼滤波方法讲解与实现
...(其他方法随时补充)

你可能感兴趣的:(滤波,信号,信号处理,matlab,开发语言)