Skip to content

MATLAB - 滤波函数

filter 函数是 MATLAB 中数字信号处理(DSP)的基本工具。它允许您实现一维(1-D)数字滤波器,这对于降噪、信号平滑、音频均衡以及分析金融时间序列数据等任务至关重要。本教程将指导您掌握有效应用这些滤波器的现代技术。

主语法 y = filter(b, a, x) 将数字滤波器应用于输入数据 x。该滤波器由一个有理传递函数定义,其中 b 是分子系数,a 是分母系数。

  • b: 分子系数向量。这些系数定义了滤波器的“零点”,对应于有限脉冲响应(FIR)分量。
  • a: 分母系数向量。这些系数定义了滤波器的“极点”,对应于无限脉冲响应(IIR)分量。对于简单的 FIR 滤波器,a 仅为 1。
  • x: 输入信号,可以是向量或矩阵。如果 x 是矩阵,filter 默认独立处理每一列。

该函数还可以处理初始条件并沿不同维度操作,为复杂应用提供了更大的灵活性: y = filter(b, a, x, zi, dim)

让我们探讨如何在现代 MATLAB 实践中使用 filter 函数。

示例 1:使用移动平均(FIR)滤波器平滑信号

Section titled “示例 1:使用移动平均(FIR)滤波器平滑信号”

移动平均滤波器是最简单的 FIR 滤波器之一,用于平滑短期波动以揭示长期趋势。它的工作原理是将每个数据点替换为其相邻数据点的平均值。

% 为确保结果的可重现性,设置随机数生成器种子
rng('default');
% 1. 定义 5 点移动平均滤波器的系数
windowSize = 5;
b = (1/windowSize) * ones(1, windowSize);
a = 1; % 这使得它成为一个 FIR 滤波器
% 2. 生成一个带噪声的信号
t = 0:0.1:20; % 时间向量
originalSignal = sin(t);
noise = 0.4 * randn(size(t));
x = originalSignal + noise; % 带噪声的输入信号
% 3. 应用滤波器
y = filter(b, a, x);
% 4. 使用 tiledlayout 现代绘图功能可视化结果
figure;
tiledlayout(2, 1);
% 顶部图:原始噪声信号
nexttile;
plot(t, x, 'Color', [0 0.4470 0.7410]);
title('Original Noisy Signal');
xlabel('Time');
ylabel('Amplitude');
grid on;
% 底部图:滤波后的信号
nexttile;
plot(t, y, 'Color', [0.8500 0.3250 0.0980], 'LineWidth', 1.5);
title('Filtered Signal (5-Point Moving Average)');
xlabel('Time');
ylabel('Amplitude');
grid on;
% 注意:观察滤波后信号的延迟,这是因果滤波器的一个特点。

示例 2:将递归(IIR)滤波器应用于矩阵数据

Section titled “示例 2:将递归(IIR)滤波器应用于矩阵数据”

IIR 滤波器是递归的,这意味着当前输出取决于过去的输入和过去的输出。它们计算效率高,但需要仔细设计以确保稳定性。在这里,我们将一个简单的低通 IIR 滤波器应用于存储在矩阵中的多个信号。

% 为确保结果的可重现性
rng('default');
% 1. 定义 IIR 滤波器系数(一个简单的低通滤波器)
b = 1;
a = [1, -0.9]; % 极点在 z=0.9,使其成为递归(IIR)滤波器
% 2. 生成一个随机阶跃信号矩阵
numSignals = 3;
signalLength = 100;
x = rand(signalLength, numSignals) + (1:numSignals); % 创建 3 个不同的信号
% 3. 沿列应用滤波器(默认行为)
y = filter(b, a, x);
% 4. 可视化第一个信号以进行比较
figure;
t = 1:signalLength;
plot(t, x(:, 1), 'DisplayName', 'Input Data');
hold on;
plot(t, y(:, 1), 'LineWidth', 2, 'DisplayName', 'Filtered Data');
hold off;
legend;
title('IIR Filtering on the First Signal');
xlabel('Sample Index');
ylabel('Value');
grid on;

现代方法是使用 MATLAB 的设计函数,而不是手动定义系数。designfilt 函数因其灵活性和可读性而备受推荐。

% 低通 FIR 滤波器的现代滤波器设计示例
Fs = 1000; % 采样频率
d = designfilt('lowpassfir', 'FilterOrder', 20, 'CutoffFrequency', 150, 'SampleRate', Fs);
% 获取与 filter() 函数一起使用的系数:
% [b, a] = tf(d);
% 对于更直接且通常更好的方法,可以直接使用设计的滤波器:
% filtered_signal = filter(d, input_signal);

对于交互式设计,滤波器设计器应用(filterDesigner)提供了一个强大的图形界面,用于设计、分析和导出滤波器。

因果滤波器会引入时间延迟。对于不可接受延迟的应用,您可以使用 filtfilt 函数进行零相位滤波。它会以正向和反向处理信号,以抵消任何相位失真。

% y_zero_phase = filtfilt(b, a, x);

滤波信号的起始部分通常包含瞬态。filter 函数可以接受初始条件 zi 来缓解这种情况,这对于分块处理数据至关重要。

  • IIR 滤波器不稳定性:如果 IIR 滤波器的输出无限增长,则表示它不稳定。当极点(a 的根)位于或超出单位圆时,就会发生这种情况。您可以使用 isstable(b, a) 检查,或使用 zplane(b, a) 可视化极点。
  • 系数顺序不正确:确保 filter 函数调用中 b(分子)和 a(分母)向量的顺序正确。
  • 忘记归一化:对于移动平均等滤波器,如果您想保持信号的整体增益,请确保系数之和为 1(sum(b))。