前言:
本文为本人在学习华科"数字信号分析理论与实践"课程所做的记录, 由于本人能力有限,在实现方法等各方面存在问题,欢迎交流指出.
本文将介绍实现最简单的FIR数字滤波器(fir1函数) ,以及附带的滤波函数(filter)
FIR 滤波器
原理分析
设计一个滤波器相当于设计一个系统,通过它的传递函数屏蔽掉不需要的输入信号,保留目标信息.
FIR(Finite Impulse Response)滤波器,即"有限长单位冲激响应滤波器",其脉冲响应是有限的持续时间,并在有限的时间内稳定为零。
其傅立叶系数h(n)实际上就是数字滤波器的冲击响应.
h ( k ) = a ( k ) , k = 0 , 1 , 2 , . . . , N h(k)=a(k),k=0,1,2,...,N
h ( k ) = a ( k ) , k = 0 , 1 , 2 , . . . , N
其单边Z变换为
H ( z ) = ∑ k = 0 N a k Z − k H(z)=\sum^N_{k=0}{a_kZ^{-k}}
H ( z ) = k = 0 ∑ N a k Z − k
理想的滤波器频率响应方程为1
H d ( ω ) = { 1 ∣ ω ∣ ≤ ω c 0 ω < ∣ ω ∣ < π H_d(\omega)=\begin{cases}
1& |\omega|\leq \omega_c \\
0& \omega<|\omega|<\pi
\end{cases}
H d ( ω ) = { 1 0 ∣ ω ∣ ≤ ω c ω < ∣ ω ∣ < π
h d ( k ) = ω c p i s i n ( ω c k ) ω c k ; k = 0 ; ± 1 , ± 2 , . . , ∞ h_d(k)=\frac{\omega_c}{pi}\frac{sin(\omega_ck)}{\omega_ck};k=0;\pm1,\pm2,..,\infty
h d ( k ) = p i ω c ω c k s i n ( ω c k ) ; k = 0 ; ± 1 , ± 2 , . . , ∞
对系数进行归一化, 即
a 0 = v 1 = f c / 1 2 f s a n = s i n ( n π v 1 ) n π ; n = 0 ; ± 1 , ± 2 , . . , ∞ \begin{aligned}
a_0 &= v_1 = {f_c}/{\frac{1}{2}f_s}\\
a_n &= \frac{sin(n \pi v_1)}{n \pi};\ n=0;\pm1,\pm2,..,\infty
\end{aligned}
a 0 a n = v 1 = f c / 2 1 f s = n π s i n ( n π v 1 ) ; n = 0 ; ± 1 , ± 2 , . . , ∞
理想的滤波器频率响应方程, 及系数计算
H d ( ω ) = { 1 ∣ ω ∣ ≥ ω c 0 o t h e r a 0 = 1 − v 1 a n = − s i n ( n π v 1 ) n π ; n = 0 ; ± 1 , ± 2 , . . , ∞ \begin{aligned}
&H_d(\omega)=\begin{cases}
1& |\omega|\geq \omega_c \\
0& other
\end{cases}\\
a_0 &= 1-v_1 \\
a_n &= -\frac{sin(n \pi v_1)} {n \pi};\ n=0;\pm1,\pm2,..,\infty
\end{aligned}
a 0 a n H d ( ω ) = { 1 0 ∣ ω ∣ ≥ ω c o t h e r = 1 − v 1 = − n π s i n ( n π v 1 ) ; n = 0 ; ± 1 , ± 2 , . . , ∞
理想的滤波器频率响应方程,及系数计算
H d ( ω ) = { 1 ω ≤ ∣ ω ∣ ≤ π 0 o t h e r a 0 = v 2 − v 1 a n = s i n ( n π v 2 ) − s i n ( n π v 1 ) n π ; n = 0 ; ± 1 , ± 2 , . . , ∞ \begin{aligned}
&H_d(\omega)=\begin{cases}
1& \omega\leq|\omega|\leq\pi \\
0&other
\end{cases}\\
a_0 &= v_2-v_1 \\
a_n &= \frac{sin(n \pi v_2)-sin(n \pi v_1)}{n \pi};\ n=0;\pm1,\pm2,..,\infty
\end{aligned}
a 0 a n H d ( ω ) = { 1 0 ω ≤ ∣ ω ∣ ≤ π o t h e r = v 2 − v 1 = n π s i n ( n π v 2 ) − s i n ( n π v 1 ) ; n = 0 ; ± 1 , ± 2 , . . , ∞
由于h(k)可能是无限长序列,是物理不可实现的,为此要寻找一个h(n),在相应的误差准则下最近逼近h(k)。
理想的滤波器频率响应方程,及系数计算
H d ( ω ) = { 0 ω ≤ ∣ ω ∣ ≤ π 1 o t h e r a 0 = 1 − ( v 2 − v 1 ) a n = − s i n ( n π v 2 ) − s i n ( n π v 1 ) n π ; n = 0 ; ± 1 , ± 2 , . . , ∞ \begin{aligned}
&H_d(\omega)=\begin{cases}
0& \omega\leq|\omega|\leq\pi \\
1&other
\end{cases}\\
a_0 &= 1-(v_2-v_1) \\
a_n &= -\frac{sin(n \pi v_2)-sin(n \pi v_1)}{n \pi};\ n=0;\pm1,\pm2,..,\infty
\end{aligned}
a 0 a n H d ( ω ) = { 0 1 ω ≤ ∣ ω ∣ ≤ π o t h e r = 1 − ( v 2 − v 1 ) = − n π s i n ( n π v 2 ) − s i n ( n π v 1 ) ; n = 0 ; ± 1 , ± 2 , . . , ∞
系数处理(窗函数法)
h ( k ) h(k) h ( k ) 可能是无限长序列,是物理不可实现的,为此要寻找一个 h ( n ) h(n) h ( n ) ,在相应的误差准则下最近逼近h ( k ) h(k) h ( k ) 。
直接截取前n各系数, 故需要通过窗函数方法对系数进行平滑处理, 减小由于截断带来的跳动.
h ( n ) = w ( n ) ⋅ a ( n ) h(n)=w(n)·a(n)
h ( n ) = w ( n ) ⋅ a ( n )
本实现中默认使用汉宁(Hamming)窗函数对系数进行平滑处理.
程序实现
首先进行进行输入参数的判断
必须要输入的参数有采样点数目 Np
,相对截止频率 v
.其中v
可以为二维数组
可选参数有 加窗类型 (通过指针p1
保存) , 滤波器类型(通过指针p2
保存)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function b = firl_fun (Np,v,varargin) N = floor (Np/2 ); narginchk(2 ,4 ); p1 = @hamming; p2 = 'low' ; switch nargin case 3 if isa(varargin{1 },'function_handle' ) p1 = varargin{1 }; else p2 = varargin{1 }; end case 4 p1 = varargin{1 }; p2 = varargin{2 }; end
然后根据所选类型进行原理中的系数计算, 完成滤波器设计.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 k=1 ; switch p2 case 'low' for i =-N:N f=i *pi ; h(k)=sin (v(1 )*f)/f; k=k+1 ; end h(N+1 )=v(1 ); case 'high' for i =-N:N f=i *pi ; h(k)=-sin (v(1 )*f)/f; k=k+1 ; end h(N+1 )=1 -v(1 ); case 'bandpass' for i =-N:N f=i *pi ; h(k)=(sin (v(2 )*f)-sin (v(1 )*f))/f; k=k+1 ; end h(N+1 )=v(2 )-v(1 ); case 'bandstop' for i =-N:N f=i *pi ; h(k)=-(sin (v(2 )*f)-sin (v(1 )*f))/f; k=k+1 ; end h(N+1 )=1 -(v(2 )-v(1 )); end b = h.*p1(2 *N+1 )'; end
实际效果
低通、高通
带通、带阻
#### 测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 clear; Fs = 2048 ; dt=1.0 /Fs; T =1 ; N=T/dt; t=[0 :N-1 ]/N; x1 =sin (2 *pi *50 *t)+sin (2 *pi *300 *t) +sin (2 *pi *500 *t); subplot(3 ,2 ,1 ); plot (t,x1); axis([0 , 0.1 , -2 ,2 ]); title("原信号时域" ); P=fft(x1,N); Pyy =2 *sqrt (P.* conj (P))/N; f=linspace (0 ,Fs/2 ,N/2 ); subplot(3 ,2 ,2 ); plot (f,Pyy(1 :N/2 ));title("原信号频域" ); type = 4 ;switch type case 1 b = fir1(48 ,0.1 ); case 2 b = fir1(48 ,0.1 ,'high' ); case 3 b = fir1(48 ,[0.1 ,0.3 ]); case 4 b = fir1(48 ,[0.1 ,0.3 ],'stop' ); end x2= filter(b,1 ,x1); switch type case 1 b2 = firl_fun(48 ,0.1 ,@hamming); case 2 b2 = firl_fun(48 ,0.1 ,@hamming,'high' ); case 3 b2 = firl_fun(48 ,[0.1 ,0.3 ],@hamming,'bandpass' ); case 4 b2 = firl_fun(48 ,[0.1 ,0.3 ],@hamming,'bandstop' ); end x3= filter_fun(b2,1 ,x1); subplot(3 ,2 ,3 ); [h,w] = freqz(b,1 ,512 ); plot (w/pi ,abs (h),'linewidth' ,1 )title("Matlab的滤波器频域图" ); subplot(3 ,2 ,5 ); plot (t,x2);axis([0 , 0.1 , -2 ,2 ]); title("Matlab的滤波器处理后" ); subplot(3 ,2 ,4 ); [h,w] = freqz(b2,1 ,512 ); plot (w/pi ,abs (h),'linewidth' ,1 )title("自写的滤波器频域图" ); subplot(3 ,2 ,6 ); plot (t,x3);axis([0 , 0.1 , -2 ,2 ]); title("自写的滤波器处理后" );
滤波器的实现
原理分析
按照Matlab的原理解释
那实现就很简单了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 function y = filter_fun (b,a,f) n = length (b); m = length (f); na = length (a)-1 ; S = zeros (1 ,m); for t=1 :n-1 S(t) = sum(f(1 :t).*fliplr (b(1 :t))) ; if na >2 if t > na S(t) = S(t) - sum( fliplr (a(2 :na+1 )).*S(t-1 :t-na)); else S(t) = S(t) - sum( fliplr (a(2 :t)).*S(1 :t-1 )); end end end for t = n:m-1 S(t) = sum(f(t-n+1 :t).*fliplr (b(1 :n))); if na >2 if t > na S(t) = S(t) - sum( fliplr (a(2 :na+1 )).*S(t-na:t-1 )); else S(t) = S(t) - sum( fliplr (a(2 :t)).*S(1 :t-1 )); end end end y = S;