目录
Matlab提供了非常丰富的滤波器设计工具,其中最基本的是designfilt()函数。 designfilt()函数是通用的滤波器设计工具,可以用于设计各种类型的数字滤波器,以及模拟滤波器的数字近似。Matlab还提供了其它很多专用类型的滤波器设计函数,还有基于图形化界面进行滤波器设计的工具filterDesigner(旧版本为fdatool)。
本文综合但简要地介绍各种matlab滤波器设计工具,顺便代码示例介绍用于滤波器频谱观测用的工具、以及如何使用所生成的滤波器对象。
以下代码示例用designfilt()设计了一个低通滤波器。
- close all; clear; clc;
- echo off;
-
- % Design a lowpass filter.
- Fs = 25e6; % Fs,passband,stopband的绝对值其实对于滤波器设计无关紧要,起作用的是相对值或者说归一化值
- passBand = 3e6; % Fs,passband,stopband的绝对值其实对于滤波器设计无关紧要,起作用的是相对值或者说归一化值
- stopBand = 6e6; % Fs,passband,stopband的绝对值其实对于滤波器设计无关紧要,起作用的是相对值或者说归一化值
- filterOrder = 30; % 设定30阶,即31抽头
- passBandFreq = (passBand)/(Fs/2); % 归一化频率计算是相对于Fs/2!
- stopBandFreq = (stopBand)/(Fs/2);
-
- filtobj = designfilt('lowpassfir', 'FilterOrder', filterOrder, ...
- 'PassbandFrequency', passBandFreq, ...
- 'StopbandFrequency', stopBandFreq, 'DesignMethod', ...
- 'ls');
- fvtool(filtobj); title('filter frequency response'); % visualize filter response
-
- % white gaussian random data generation
- noise = wgn(1,10000,0,'dBm'); % 生成0dBm高斯白噪声序列
-
- % filtering
- filted_out1 = filter(filtobj,noise); % 直接以滤波器对象作为参数调用filter
- filted_out2 = filter(filtobj.Coefficients,1,noise); % 以filter(b,a,x)的方式调用
-
- assert(isequal(filted_out1,filted_out2)); % 确认两种调用方法的结果是否完全一致
-
- figure;
- subplot(2,1,1); pwelch(noise,[],[],[],Fs,'center'); title('original noise');
- subplot(2,1,2);
- pwelch(filted_out1,[],[],[],Fs,'center'); title('after filtering');
- hold on;
- pwelch(filted_out2,[],[],[],Fs,'center');
-
- echo off;
所生成的滤波器的幅频响应(由fvtool()生成)如下:
滤波器的输入信号频谱(白噪声,所以基本上功率谱密度是均一的)和输出信号频谱分别如下所示(可以看出输出频谱相对于输入频谱的变化体现了滤波器的幅频响应):
“passbandFrequency”和“stopbandFrequency”的设定是以归一化频率的形式进行设定,进一步,是相对于奈奎斯特频率(Fs/2, instead of Fs!)的归一化频率。
designFilt()生成的是digitalFilter类的对象。根据所生成的滤波器的类型,该对象中所包含的信息是不同的。比如说以上生成的低通滤波器对象中所包含的信息为:
filtobj =
digitalFilter with properties:
Coefficients: [-6.6250e-04 -5.5486e-04 0.0017 0.0037 3.1161e-04 -0.0082 -0.0103 0.0049 0.0253 0.0192 -0.0256 -0.0658 … ]
Specifications:
FrequencyResponse: 'lowpass'
ImpulseResponse: 'fir'
SampleRate: 2
FilterOrder: 30
StopbandFrequency: 0.4800
PassbandFrequency: 0.2400
DesignMethod: 'ls'
所生成的滤波器可以作为输入参数传递给filter()进行滤波处理。这里有两种基本的调用方式:
第一种是直接将滤波器对象作为参数传递给filter():filter(filtobj,noise);
第二种是以filter(b,a,x)的方式只将滤波器对象中滤波器系数传递给filter(): filter(filtobj.Coefficients,1,noise);
designfilt()功能非常强大,几乎无所不能。这里只做简要介绍,详细使用说明可以参考matlab帮助页信息。
designfilt()的“resp”参数用于指定所要设计的滤波器响应的类型,有以下可能的选项:
'lowpassfir' | FIR低通滤波器 | |
'lowpassiir' | IIR低通滤波器 | |
'highpassfir' | FIR高通滤波器 | |
'highpassiir' | IIR高通滤波器 | |
'bandpassfir' | FIR带通滤波器 | |
'bandpassiir' | IIR带通滤波器 | |
'bandstopfir' | FIR带阻滤波器 | |
'bandstopiir' | IIR带阻滤波器 | |
'differentiatorfir' | FIR差分器 | |
'hilbertfir' | FIR希尔伯特滤波器 | |
'arbmagfir' | 任意幅频响应滤波器 |
针对每种滤波器类型,有各不相同的设计参数指定方式,详细请查询matlab帮助页。
designfilt()使用参数“DesignMethod”来指定设计优化方法,设计优化有以下一些可选项:
'butter' | 设计巴特沃斯类型的IIR滤波器 |
'cheby1' | 设计切比雪夫类型1的IIR滤波器 |
'cheby2' | 设计切比雪夫类型2的IIR滤波器 |
'cls' | 使用约束最小二乘法设计FIR滤波器 |
'ellip' | 设计椭圆类型IIR滤波器 |
'equiripple' | 使用Parks-McClellan algorithm设计等波纹FIR滤波器 |
'freqsamp' | 使用频域采样法设计任意频率响应的FIR滤波器 |
'kaiserwin' | 使用恺撒窗方法设计FIR滤波器 |
'ls' | 使用最小二乘法设计FIR滤波器 |
'maxflat' | 设计最大平坦FIR滤波器 |
'window' | 使用最小平方近似方法计算滤波器系数,然后用窗函数进行平滑化 |
很显然,设计方法与设计类型并不是能够进行全组合的关系,因为有些设计方法只能用于IIR滤波器设计,有一些则只能用与FIR滤波器的设计。
针对每种设计方法,有各不相同的辅助参数指定方式,详细请查询matlab帮助页。
在matlab命令行输入以下命令会输出所有滤波器相关的各种工具以及示例列表。
后面将挑选一些典型常用的设计工具函数进行基于代码实验的介绍。
>> lookfor 'filter design'
除了以上designfilt()可以选择指定"butter"选项设计巴特沃斯滤波器,matlab也提供了butter()函数专门用于巴特沃斯滤波器。代码示例如下:
- % butterworth filter designfilt
- [b1,a1] = butter(4,0.6,'low'); % 4阶巴特沃斯低通滤波器
- [b2,a2] = butter(4,0.3,'high');% 4阶巴特沃斯高通滤波器
- figure; freqz(b1,a1); title('4th-order butterworth low-pass filter, freq response');
- figure; freqz(b2,a2); title('4th-order butterworth high-pass filter, freq response');
- % white gaussian random data generation
- noise = wgn(1,10000,0,'dBm'); % 生成功率为0dBm的高斯白噪声
-
- filted_out1 = filter(b1,a1,noise);
- filted_out2 = filter(b2,a2,filted_out1); % 低通和高通级联等价于一个带通滤波器
-
- figure;
- subplot(3,1,1); pwelch(noise,[],[],[],[],'center'); title('original noise');
- subplot(3,1,2); pwelch(filted_out1,[],[],[],[],'center'); title('after low-pass filtering');
- subplot(3,1,3); pwelch(filted_out2,[],[],[],[],'center'); title('after high-pass filtering');
4阶巴特沃斯低通和高通滤波器的频域响应如下所示(这是iir类型的滤波器,所以不是线性相位的) 。
输入信号和输出信号频谱如下所示,很显然,一个低通滤波处理和一个高通滤波器级联得到了一个带通滤波器处理的效果。
半带滤波器可以用firhalfband()生成,代码例如下。
- Fs = 25e6;
- Fp = 3e6;
- N = 20;
- hbfir1 = firhalfband(N,Fp/(Fs/2));
- fvt1 = fvtool(hbfir1,'Fs',Fs,'Color','white');
- figure; plot(hbfir1,'-o'); grid on; title('impulse response');
半带滤波器常用于2倍上采样的镜像抑制滤波器或2倍下采样的抗混叠滤波器。通常将半带滤波器与 2倍上采样或2倍下采样组合在一起构成所谓的半带抽取器(halfband decimator)和半带插值器(halfband interpolator)。进一步可以以级联的方式构成更复杂的多级高倍率上采样插值滤波器或者下采样抽取器。
Also: IIR滤波器设计基础及Matlab设计示例https://chenxiaoyuan.blog.csdn.net/article/details/125363150