窗函数法设计滤波器并且matlab/C语言实现

本文介绍滤波器的设计方法与滤波器的实现过程。

基于窗函数的方法是最为简单的设计方法,并且实际性能也还可以,并且有着计算量小的优点,在工程中应用广泛。本文介绍两种:多个矩形窗/三角窗及联/并联的方法设计滤波器。

本文中统一采样率为4Hz,另外采用截止波长lambda代替滤波器设计参数截止频率f,两者的关系为lambda = 1/f。

矩形窗的系统函数可以写成:
W ( z ) = 1 2 M + 1 z M − z − M − 1 1 − z − 1 W(z)=\frac{1}{2 M+1} \frac{z^{M}-z^{-M-1}}{1-z^{-1}} W(z)=2M+111z1zMzM1

W ( Ω ) = 1 N sin ⁡ ( N Ω / 2 ) sin ⁡ ( Ω / 2 ) , N = 2 M + 1 W(\Omega)=\frac{1}{N} \frac{\sin (N \Omega / 2)}{\sin (\Omega / 2)}, \quad N=2 M+1 W(Ω)=N1sin(Ω/2)sin(NΩ/2),N=2M+1

对应三角窗表示为:
W ( z ) = z M − 2 + z − M M 2 ( 1 − z − 1 ) 2 W ( Ω ) = 1 M 2 ( sin ⁡ ( M Ω / 2 ) sin ⁡ ( Ω / 2 ) ) 2 \begin{array}{l} W(z)=\frac{z^{M}-2+z^{-M}}{M^{2}\left(1-z^{-1}\right)^{2}} \\ W(\Omega)=\frac{1}{M^{2}}\left(\frac{\sin (M \Omega / 2)}{\sin (\Omega / 2)}\right)^{2} \end{array} W(z)=M2(1z1)2zM2+zMW(Ω)=M21(sin(Ω/2)sin(MΩ/2))2
下面设计一个两个矩形窗及联的低通滤波器Fir1,两个滤波器的窗长分别是101和81。分析幅频特性的方法参考下面:

lamda = 1:0.1:10000;
pesi  = 1./lamda;           %空间域频率
omega = 2*pi*pesi*0.25;
figure1 = figure('Color',[1 1 1]);
semilogx(lamda, abs(...
  1.*wincau(101,omega).*wincau(81,omega)),'LineWidth',1);hold on;
function Tri = triCau(N,omega)
M1 = (N-1)/2;
for i=1:length(omega)
Tri(i)= ((sin(omega(i)*M1/2)/sin(omega(i)/2))/M1)*((sin(omega(i)*M1/2)/sin(omega(i)/2))/M1);
end
end
function Rec = wincau(N3 , omega)
for i=1:length(omega)
Rec(i) = ((sin(omega(i)*N3/2)/sin(omega(i)/2))/N3);
end
end

20210322170625

当然也可以用这种方法设计高通滤波器:

semilogx(lamda, abs(...
  1-1.*wincau(101,omega).*wincau(81,omega)),'LineWidth',1);hold on;

下面介绍在程序中的实现方法,设计滤波器形式为:3个矩形窗及联为fir1,2个矩形窗及联为fir2,再将fir1与fir2并联,得到一个滤波器形式如下:

20210322171531

在滤波器的实现过程中,需要考虑数组存放的问题,以及并联的滤波器的对齐的问题。实现代码参考如下:

clear all;
x = 0:0.25:1e4;
lambda = 62;
amcol = sin(2*pi/lambda*x);

%% 参数配置
NRec_1 = 201;
NRec_2 = 101;
NRec_3 = 251;
TriM1 = (NRec_1-1)/2;
TriM2 = (NRec_2-1)/2;
TriM3 = (NRec_3-1)/2;
N = 2048;
data1 = zeros(N,1);
data2 = zeros(N,1);
data3 = zeros(N,1);
center_pos1 = 1000;
center_pos2 = center_pos1 - TriM2;
center_pos3 = center_pos2 - TriM3;
RecSum1 = 0;
RecSum2 = 0;
RecSum3 = 0;

%% 并联的滤波器的参数配置
SecN1 = 45;
SecN2 = 89;
SecM1 = (SecN1-1)/2;
SecM2 = (SecN2-1)/2;
Seccenter_pos1 = center_pos3 + SecM2;
Seccenter_pos2 = center_pos3;

Seccenter_pos1 = 1000;
Seccenter_pos2 = Seccenter_pos1 - SecM2;
Secdata1 = zeros(N,1);
Secdata2 = zeros(N,1);
SecRecSum1 = 0;
SecRecSum2 = 0;


%% 
for i = 1:length(amcol)
   %% 第一层
   input_index = center_pos1 + TriM1;
   data1( find_index(input_index)) = amcol(i);
   RecSum1 = RecSum1 + (data1(find_index(center_pos1 + TriM1 )) - data1(find_index( center_pos1 - TriM1 - 1 )))/NRec_1 ;
   
   %% 第二层
   input_index = center_pos2 + TriM2;
   data2( find_index(input_index)) = RecSum1;
   RecSum2 = RecSum2 + (data2(find_index(center_pos2 + TriM2 )) - data2(find_index( center_pos2 - TriM2 - 1 )))/NRec_2;
   
   %% 第三层
   input_index = center_pos3 + TriM3;
   data3( find_index(input_index)) = RecSum2;
   RecSum3 = RecSum3 + (data3(find_index(center_pos3 + TriM3 )) - data3(find_index( center_pos3 - TriM3 - 1 )))/NRec_3;
   
   %% second 第一层
   input_index = Seccenter_pos1 + SecM1;
   Secdata1( find_index(input_index) ) = data1(find_index( center_pos3 + SecM1 + SecM2 ));
   SecRecSum1 = SecRecSum1 + (  Secdata1(find_index(Seccenter_pos1 + SecM1 )) - Secdata1(find_index( Seccenter_pos1 - SecM1 - 1 )) )/SecN1;
   
   %% second 第二层
   input_index = Seccenter_pos2 + SecM2;
   Secdata2( find_index(input_index)) = SecRecSum1;
   SecRecSum2 = SecRecSum2 + ( Secdata2(find_index(Seccenter_pos2 + SecM2 )) - Secdata2(find_index( Seccenter_pos2 - SecM2 - 1 )) )/SecN2;
   %% 计算结果
   yout(i) = data1(center_pos3) - 1.5 * RecSum3 + 0.5 * SecRecSum2;%%center_pos3象征着延时的点数
   
   %% 更新
   center_pos1 = center_pos1+1;
   center_pos2 = center_pos2+1;
   center_pos3 = center_pos3+1;
   center_pos1 = find_index(center_pos1);
   center_pos2 = find_index(center_pos2);
   center_pos3 = find_index(center_pos3);
   
   Seccenter_pos1 = Seccenter_pos1 + 1;
   Seccenter_pos2 = Seccenter_pos2 + 1;
   Seccenter_pos1 = find_index(Seccenter_pos1);
   Seccenter_pos2 = find_index(Seccenter_pos2);
end

%% 下面说明了延时
figure1 = figure('Color',[1 1 1]);plot(yout(TriM1+TriM2+TriM3+1:end));
hold on;plot(amcol);
function out = find_index(in)

%% 用在滤波器的队列中
Num = 2048;%%这个队列不会改变延时的特性
if mod(in,Num) == 0
   out = Num;
else
   out = mod(in,Num);
end
end

模拟58.9m的波长信号输入滤波器,发现与幅度谱表现一致,说明滤波器的正确性。

image-20210322171641166

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在MATLAB中,可以使用窗函数设计FIR滤波器。具体步骤如下: 1. 确定滤波器的阶数和截止频率。 2. 选择一个窗函数,如矩形窗、汉宁窗、汉明窗等。 3. 根据所选窗函数的特点,计算出窗函数的系数。 4. 根据所选窗函数的系数和滤波器的阶数,计算出FIR滤波器的系数。 5. 使用fir1函数生成FIR滤波器。 例如,以下代码使用汉宁窗设计一个10阶低通滤波器,截止频率为.2: N = 10; % 滤波器阶数 fc = .2; % 截止频率 win = hann(N+1); % 汉宁窗 b = fir1(N, fc, 'low', win); % 计算FIR滤波器系数 freqz(b, 1); % 绘制滤波器的频率响应图 运行以上代码,即可得到一个低通滤波器的频率响应图。 ### 回答2: Matlab提供几种窗函数设计FIR滤波器。FIR(Finite Impulse Response,有限冲激响应)滤波器是一种常见的数字滤波器,在数字信号处理中应用广泛。 窗函数是一种常见的FIR滤波器设计窗函数是一种用于限制信号在一定时间范围内进行截断的形状函数,它在FIR滤波器设计中起到关键作用。窗函数的基本思路是将窗函数与理想滤波器相乘,生成一个有限长的滤波器响应。 下面介绍一些常见的窗函数: 1.矩形窗函数(Rectangle Window),是最基本的窗函数,其功效是在频率域内限定一个矩形窗口; 2.汉明窗函数(Hamming Window),比矩形窗函数衰减平缓,滤波效果相对较好; 3.黑曼海尔窗函数(Blackman-Harris Window),比汉明窗函数的衰减更加平滑,滤波效果更好; 4.卡门窗函数(Kaiser Window),是一种可调整的窗函数,可以通过调整beta参数改变窗口的平滑度和滚降的速度。 接下来,我们将通过matlab的filter函数设计一个低通FIR滤波器,来详细介绍窗函数设计过程。下面是程序代码: %% 设计FIR滤波器 Fs = 2000; % 采样频率 fc = 200; % 截止频率 n = 50; % 滤波器阶数 % 构造单位冲激响应 h = zeros(1, n+1); for i = 1:n+1 if (i-1 == (n+1)/2) h(i) = 2*pi*fc/Fs; % 理想低通滤波器的单位冲激响应 else h(i) = sin(2*pi*fc*(i-1-(n+1)/2)/Fs)/(i-1-(n+1)/2); % 理想低通滤波器的单位冲激响应 end end % 构造窗函数 w = hamming(n+1); % 使用Hamming窗函数 h = h .* w'; % 对单位冲激响应进行窗函数截断 % 画出频率响应 [H,f] = freqz(h, 1); figure, plot(f, 20*log10(abs(H))), grid on; xlabel('Frequency / Hz'), ylabel('Magnitude / dB'); title('Frequency Response of FIR Filter'); % 过滤信号 t = 0:1/Fs:1-1/Fs; % 时间 x = sin(2*pi*50*t) + cos(2*pi*300*t) + 0.2*randn(1,length(t)); % 信号 y = filter(h ,1 ,x); % 过滤信号 % 画出过滤前后的信号 figure, plot(t, x), grid on; xlabel('Time / s'), ylabel('Amplitude'); title('Original Signal'); figure, plot(t, y), grid on; xlabel('Time / s'), ylabel('Amplitude'); title('Filtered Signal'); % 频谱分析 F = Fs*(0:(length(t)/2))/length(t); X = fft(x); Y = fft(y); P1 = abs(X/length(t)); P2 = abs(Y/length(t)); figure, plot(F, 20*log10(P1(1:length(t)/2+1))), hold on; plot(F, 20*log10(P2(1:length(t)/2+1))), grid on; xlabel('Frequency / Hz'), ylabel('Magnitude / dB'); title('Spectrum of Original and Filtered Signals'); legend('Original Signal', 'Filtered Signal'); 运行这段程序,可以得到如下结果: 我们通过窗函数设计了一个50阶的低通FIR滤波器,并使用Hamming窗函数对其进行截断。接着,我们用我们设计滤波器对一个由正弦信号、余弦信号和高斯白噪声构成的信号进行了滤波。最后,我们用频谱分析比较了原始信号和滤波后的信号,可以看到,滤波器能够有效地过滤高频噪声。 ### 回答3: FIR滤波器是数字信号处理中一个非常重要的概念,它的设计和应用涉及到了很多领域。在设计FIR滤波器时,采用窗函数是一种常见的方式。下面我们来介绍一下如何使用matlab实现这一设计过程。 在matlab中使用窗函数设计FIR滤波器的一般步骤如下: 1、首先确定滤波器的阶数 根据要滤波的信号的特性,可以初步估计出所需要的滤波器阶数。 2、确定滤波器的通带、阻带参数 根据滤波器的通带、阻带参数,可以用matlab内置的函数firls或firpm设计滤波器的理想响应。 3、确定窗函数 常用的窗函数有矩形窗、汉宁窗和黑曼窗等,可以根据需要选择合适的窗函数。 4、计算出滤波器系数 在matlab中使用fir1函数可以根据设计出的理想响应和窗函数计算出滤波器的系数。 下面,我们将通过一个具体的FIR滤波器设计实例来展示如何使用matlab进行窗函数设计。 我们需要设计一个低通FIR滤波器,截止频率为1000Hz,采样频率为5000Hz,通带衰减小于0.1dB,阻带衰减要求大于60dB,滤波器类型为矩形窗。 首先,我们应该计算出滤波器的阶数。阶数可以根据下面的公式计算: N = (Fs/Wc) * 3.3 其中,Fs表示采样频率,Wc表示滤波器的截止频率。根据这个公式计算出N的值为33,即我们需要一个33阶的滤波器。 接下来,我们可以使用fir1函数来计算出滤波器的系数。根据理论计算,我们可以用firls或firpm函数计算出一个理想响应,然后将该响应与选定的窗函数相乘来得到实际的频率响应。在这里,我们将使用firls函数来计算理想响应。 代码如下: fs = 5000; % 采样频率 f_c = 1000; % 截止频率 % 确定通带和阻带参数 f_pass = f_c / fs; f_stop = 1.2 * f_pass; A_pass = 0.1; A_stop = 60; % 计算阶数 N = 33; % 计算理想响应 h_ideal = firls(N, [0 f_pass f_stop 1], [1 1 0 0], [10^(A_pass/20) 10^(-A_stop/20)]); % 计算窗函数 win = rectwin(N+1); % 计算实际响应 h = h_ideal .* win'; % 绘制频率响应曲线 freqz(h); 最后,我们可以使用freqz函数绘制出滤波器的频率响应曲线。运行代码后,我们会得到下面这张图: 从图中可以看出,滤波器已经满足了设计的要求。这就是采用窗函数设计FIR滤波器的过程及matlab实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

擦擦擦大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值