我制作了一个简单的一阶 IIR 高通滤波器,在 z = 1 处为零,在 z = 0.9 处有一个极点。它的频率响应如下所示:
现在,我使用此滤波器过滤直流信号。这是我用来执行此操作的 MATLAB 代码:
b = [1 -1]; % Zero at z = 1
a = [1 -0.9]; %Pole at z = 0.9
figure(1)
freqz(b, a)
t = 1:100;
x(1:length(t)) = 1; % Constant function
y = filter(b, a, x);
figure(2)
plot(t, x)
xlabel('Time');
ylabel('Input Signal');
figure(3)
plot(t, y)
xlabel('Time');
ylabel('Output Signal');
由于我的滤波器是高通的,我预计 DC 会变为零,或者至少会严重衰减。但是,我得到的输出信号如下所示:
据我了解,这个指数输出是由于我没有正确设置初始条件而产生的瞬态。果然,设置 x[-1] = 1 解决了这个问题。然而,这只适用于这个特定的输入直流信号。对于任何通用输入信号,我如何设置初始条件以免产生瞬变?
编辑:我知道 filtfilt() 函数通过瞬态最小化进行前向后向过滤,但我真的想将过滤器移植到嵌入式平台,所以我需要了解瞬态删除的工作原理。在此先感谢您的帮助!
编辑 2:正如 Kuba Ober 所建议的,我尝试将 x[-1] 设置为它实际上应该是的值。它适用于直流输入,但对于正弦输入来说,情况如下:
clc; clear all;
p = 0.9
a = [1 -p]
b = [1 -1]
n = 1:100; % Samples
f = 0.2; % Frequency in Hz
Fs = 10; % Sampling rate in samples per second
t = n/Fs; % Time axis
x = sin(2*pi*f*t);
% Filter with the appropriate initial conditions
y = filter(b, a, x, filtic(b, a, [], [sin(2*pi*f*0)]));
figure(1)
plot(t, x)
xlabel('Time');
ylabel('Input Signal');
figure(2)
plot(t, y)
xlabel('Time');
ylabel('Output Signal');
这是输入信号:
这是输出:
第一个峰值明显小于第二个峰值,这表明存在一些瞬变。我对此并不完全确定,但我认为它不起作用的原因是因为仅设置 x[-1] 是不够的,我还需要设置 y[-1]。这里的问题是没有办法找出 y[-1] 实际上应该是什么。
编辑 3:让我提供有关我正在处理的问题的更多信息。我正在尝试使用滤波器来消除嵌入式平台中 ECG(心电图)信号中的噪声。这是过滤后的典型心电图信号:
以下是 ECG 信号在过滤前的样子:
注意滤波前信号中的直流偏移。对于滤波,我需要一个陷波滤波器来去除高频电源线噪声和一个高通滤波器来去除直流和信号的低频“漂移”。
我使用的滤波器需要是线性相位的,因为 ECG 信号的时域形态对于诊断非常重要。但是,我的过滤器不需要是实时的,因为我在从患者那里获取 ECG 信号后离线进行处理。因此,为了实现非线性相位 IIR 滤波器,我目前正在使用前向后向零相位滤波。
@Matt L. 和 @Royi 共享的一个观点是瞬态在实时滤波中是不可避免的,我应该使用更长的输入信号并剪掉滤波输出的前几秒。这是我想避免的事情,因为从活着的病人那里获取长的心电图有点困难。此外,我不必实时过滤,因此任何依赖于提前了解整个信号的瞬态去除技术都是完全可以的。任何帮助表示赞赏!