【建议收藏】用MATLAB自动生成滤波器的傻瓜方法

本文介绍MATLAB中滤波器的定义和设置,以及各个参数的含义。
一、读取信号
>> [y,Fs] = audioread(filename)
y是信号,Fs是采样率,filename是音频文件路径。
二、傅里叶变换
>> Fs = 1000; %采样率
>> T = 1/Fs; %采样周期
>> L = 1500; %信号长度
>> t = (0:L-1)*T; %时间向量
%构造一个信号,其中包含振幅为 0.7 的 50 Hz 正弦信号和振幅为 1 的 120 Hz 正弦信号。
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
%傅里叶变换
>> Y = fft(S);
>> P2 = abs(Y/L);
>> P1 = P2(1:L/2+1);
>> P1(2:end-1) = 2*P1(2:end-1);
>> plot(f,P1)
>> title('Single-Sided Amplitude Spectrum of S(t)')
>> xlabel('f (Hz)') ylabel('|P1(f)|')

见说明文档:
三、自相关
互相关用于拾取相似信号。
>> r = xcorr(signal1,signal2);
>> plot(r);
四、滤波器
简单来说滤波器就是滤掉特定频率范围的信号,例如对于一首歌,我们可以滤掉人声的频率范围,以得到纯音乐。
滤波器:
我们可以使用MATLAB的滤波器设计器,在命令行中输入
>> designfilt
然后就会弹出滤波器类型:
低通(Lowpass),高通(Highpass),带通(Bandpass),带阻(Bandstop)等等。其中FIR和IIR分别是有限/无限(Finite,Infinite)脉冲响应的意思。

我们选用常用的低通滤波器,也就是只允许某个 频率以下的成分通过。点击确认弹出界面:

注意到有一些参数

1.Frequency Units:频率单位。这里建议选择具体的频率,即Hz
2.Input sample rate:输入的信号采样率,也就是一秒钟采样多少个点。采样率越高信号质量越好。
3.Passband frequency和Stopband frequency:有人问,低通滤波不就一个低通上限吗,为什么是两个参数。这是因为你脑子里的这种只有一个低通上限的滤波器是理想矩形滤波器,即低于上限频率的全通过,高于上限频率的全不通过;

而实际上,上面的滤波器是做不出来的。上限频率是一个范围,是逐渐衰减的。因此你要选择从多大的频率衰减,到多大的频率衰减到0.如下图所示:

一般来说,你要确保截止频率以上的频率成分全都不能通过,因此你就要设置Stop Frequency为截止频率。而Pass frequency设多少,取决于你自己的需求:设置得越陡峭,对截止频率以下的成分的影响越小,则滤波效果越好,而滤波器的阶数也越高,则计算时间也越长;反之,设置得越平缓,则对截止频率附近的信号影响越大。
下面是振幅参数:

Passband ripple和Stopband attenuation就是下面的意思:说白了就是描述你截止频率附近的起伏大小,也就是对截止频率附近信号成分的畸变作用的大小。

最后是选择算法

请注意,如果你看不懂下面的内容,你根本无需在意选择哪种算法:
Kaiser window就是用Kaiser窗函数来滤波,它使得信号主瓣和旁瓣的能量比最大,也就是说,抑制旁瓣能量。


而equiripple,顾名思义,就是让ripple等大小波动,这是为了抑制截止频率附近的信号畸变。

设置完成!点击OK后matlab会自动计算符合条件的滤波器,请耐心等待。

计算完成后会把设计好的滤波器输出在命令行中:

生成的第一行就是我们要的滤波器代码
>> designfilt('lowpassfir', 'PassbandFrequency', 10, 'StopbandFrequency', 12, 'PassbandRipple', 1, 'StopbandAttenuation', 60, 'SampleRate', 1000);
然后怎么用呢?
1.首先令myfilt=前面一串,定义了名字为"myfilt"的滤波器
>> myfilt=designfilt('lowpassfir', 'PassbandFrequency', 10, 'StopbandFrequency', 12, 'PassbandRipple', 1, 'StopbandAttenuation', 60, 'SampleRate', 1000);
注意到参数实际上是可以直接在这里改的。
2.查看滤波器,以检查是否满足你的需求
>> fvtool(myfilt);

3.进行零相移滤波
>> signal_filt=filtfilt(myfilt,signal);
注意你信号的采样率要和你之前设计的滤波器的采样率一样。
什么叫零相移滤波呢,就是说滤波以后信号不因滤波器的影响发生相移。MATLAB的实现方法就是滤波两次,使得相移相抵消。
贴一段MATLAB官方教程演示这个问题:
>> wform = ecg(500);
>> plot(wform);
>> axis([0 500 -1.25 1.25]);
>> text(155,-0.4,'Q');
>> text(180,1.1,'R');
>> text(205,-1,'S')
生成模拟信号:

>> rng default
>> x = wform' + 0.25*randn(500,1);
>> d = designfilt('lowpassfir', ... 'PassbandFrequency',0.15,'StopbandFrequency',0.2, ... 'PassbandRipple',1,'StopbandAttenuation',60, ... 'DesignMethod','equiripple');
>> y = filtfilt(d,x);
>> y1 = filter(d,x);
>> subplot(2,1,1)
>> plot([y y1])
>> title('Filtered Waveforms')
>> legend('Zero-phase Filtering','Conventional Filtering')
>> subplot(2,1,2)
>> plot(wform)
>> title('Original Waveform')
零相移滤波器和非零相移滤波器的滤波结果与原始信号对比,结果显示非零相移滤波器导致信号峰值位置发生移动,也就是所谓“相移”。

至于高通滤波、带通滤波,和低通滤波的定义大同小异,都是要设置开始衰减的频率,和结束衰减的频率。