之前的两篇文章分别介绍了FIR和IIR的基础理论,这一篇我们将介绍其在MATLAB中的具体实现方法。
MATLAB为滤波设置了种工具,比如图形化的设计工具filterDesginer、根据差分方程直接设计滤波器的filter函数、根据滤波目的进行设计的lowpass函数、highpass函数等等。
不过我最终选用了designfilt函数进行FIR、IIR滤波器设计实现。因为该函数兼具了方法的全面性和统一性,而且相对于图形界面,纯代码的形式在很多场景下也更便于调用。
这里我们举一个例子来说明designfilt函数的用法。
准备滤波的对象数据如下,我们对该数据进行低通滤波:
滤波前数据
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为滤波后数据
此时绘制一下滤波前数据和滤波后数据的对比图:
可以看到滤波结果是有相位延迟的,对于相位延迟,在之前的文章中也介绍过。由于FIR滤波的相位延迟是线性的,可以通过平移进行延迟补偿(不用担心,IIR滤波器也可以相位补偿):
相位补偿后的结果
四、关于designfilt函数的其他规范集
这里要提到一个“规范集”的概念,可以看一下下图:
lowpassfir的规范集
上图是lowpassfir的规范集,对于其他七种方法,都有这样一张规范集列表。所谓的“规范集”简单来说就是designfilt函数支持不同的滤波器设计方法(这里的设计方法不是指FIR或者IIR,而是更加细分的“window、butter”等等),而在不同的设计方法中,需要输入的各种参数都会有所不同。而上表就是列出在不同的设计方法下需要设置哪些参数。
我们在上边程序中用到的规范集是下边红框框出来的这一行:
如果在你的研究需求中,要使用其他规范集,就需要参考到这张表了。
通过上述方法结合官方教程文档,我们可以实现滤波器的设计,但是对于新手来说多少还是有一些门槛的,而且对于很多应用场景,我们并不需要考虑那么多种规范集形式。
有没有一种更简便易用,兼顾专业性,最好还可以多功能分析和画图的实现方法呢?
现在有了——笔者按照专栏以往的的代码风格,对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);
就可以得到如下结果:
图1. 滤波器响应图
图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滤波算法 | 工具箱文档
目前计划要讲到的包括:
-1.FIR有限冲激响应、IIR无限冲激响应数字滤波算法的理论讲解、滤波器设计方法和MATLAB代码实现
-2.滤波器滤波效果的评价指标
-3.“类EMD”方法(即包括EMD、EEMD、CEEMD、VMD等一系列方法)的滤波算法讲解与实现
-4.“类EMD”方法与ICA结合的滤波算法讲解与实现
-5.小波阈值滤波方法讲解与实现
-6.卡尔曼滤波方法讲解与实现
...(其他方法随时补充)