主要内容

filtfilt

零相位数字滤波

说明

y = filtfilt(b,a,x) 通过正向和反向处理输入数据 x 来执行零相位数字滤波。在对数据进行正向滤波后,该函数会匹配初始条件以最大限度地减少启动和结束时的瞬变,反转滤波后的序列,并让反转后的序列再次通过滤波器。结果具有以下特征:

  • 零相位失真

  • 滤波器传递函数等于原始滤波器传递函数的平方幅值

  • 滤波器阶数是由 ba 指定的滤波器阶数的两倍

不要将 filtfilt 与微分器和希尔伯特 FIR 滤波器结合使用,因为这些滤波器的运算在很大程度上取决于它们的相位响应。

示例

y = filtfilt(sos,g,x) 使用由矩阵 sos 和尺度值 g 表示的二阶节 (biquad) 滤波器对输入数据 x 进行零相位滤波。

y = filtfilt(d,x) 使用数字滤波器 d 对输入数据 x 进行零相位滤波。使用 designfilt 根据频率响应设定生成 d

示例

y = filtfilt(B,A,x,"ctf") 零相位使用由分子系数和分母系数(分别为 BA)定义的Cascaded Transfer Functions (CTF) 对输入数据 x 进行滤波。 (自 R2024b 起)

注意

当您将 A 指定为标量或向量时,指定 "ctf" 选项以将具有六列的 CTF 分子矩阵 B 与二阶节矩阵输入 sos 区分开来。

示例

y = filtfilt({B,A,g},x) 在输入数据 x 的滤波中包括滤波器标量值 g (自 R2024b 起)

示例

y = filtfilt(___,Name=Value) 使用名称-值参量指定附加选项。 (自 R2026a 起)

示例

全部折叠

零相位滤波有助于将滤波后的时间波形中的特征准确地保留在它们在未经滤波的信号中出现的位置。

对合成心电图 (ECG) 波形进行零相位滤波。生成波形的函数在示例的末尾。QRS 复波是 ECG 的一个重要特征。如下图所示,它在时间点 160 左右开始。

wform = ecg(500);

plot(wform)
axis([0 500 -1.25 1.25])
text(155,-0.4,"Q")
text(180,1.1,"R")
text(205,-1,"S")

Figure contains an axes object. The axes object contains 4 objects of type line, text.

用加性噪声损坏 ECG。重置随机数生成器以获得可重现的结果。构造一个低通 FIR 等波纹滤波器,并使用零相位滤波和传统滤波对含噪波形进行滤波。

rng("default")

x = wform' + 0.25*randn(500,1);
d = designfilt("lowpassfir", ...
    PassbandFrequency=0.15,StopbandFrequency=0.2, ...
    PassbandRipple=1,StopbandAttenuation=60, ...
    DesignMethod="equiripple");
y = filtfilt(d,x);
y1 = filter(d,x);

tiledlayout("flow")
nexttile
plot([y y1])
title("Filtered Waveforms")
legend(["Zero-phase Filtering" "Conventional Filtering"])

nexttile
plot(wform)
title("Original Waveform")

Figure contains 2 axes objects. Axes object 1 with title Filtered Waveforms contains 2 objects of type line. These objects represent Zero-phase Filtering, Conventional Filtering. Axes object 2 with title Original Waveform contains an object of type line.

零相位滤波可减少信号中的噪声,并在原始信号中出现 QRS 复波的同时保留该复波。传统滤波可减少信号中的噪声,但会使 QRS 复波延迟。

使用巴特沃斯二阶节滤波器重复进行滤波。

d1 = designfilt("lowpassiir",FilterOrder=12, ...
    HalfPowerFrequency=0.15,DesignMethod="butter");
y = filtfilt(d1,x);

figure
plot(x)
hold on
plot(y,LineWidth=3)
hold off
legend(["Noisy ECG" "Zero-Phase Filtering"])

Figure contains an axes object. The axes object contains 2 objects of type line. These objects represent Noisy ECG, Zero-Phase Filtering.

此函数生成 ECG 波形。

function x = ecg(L)
%ECG Electrocardiogram (ECG) signal generator.
%   ECG(L) generates a piecewise linear ECG signal of length L.
%
%   EXAMPLE:
%   x = ecg(500).';
%   y = sgolayfilt(x,0,3); % Typical values are: d=0 and F=3,5,9, etc. 
%   y5 = sgolayfilt(x,0,5); 
%   y15 = sgolayfilt(x,0,15); 
%   plot(1:length(x),[x y y5 y15]);

%   Copyright 1988-2002 The MathWorks, Inc.

a0 = [0,1,40,1,0,-34,118,-99,0,2,21,2,0,0,0]; % Template
d0 = [0,27,59,91,131,141,163,185,195,275,307,339,357,390,440];
a = a0/max(a0);
d = round(d0*L/d0(15)); % Scale them to fit in length L
d(15)=L;

for i=1:14
       m = d(i):d(i+1)-1;
       slope = (a(i+1)-a(i))/(d(i+1)-d(i));
       x(m+1) = a(i)+slope*(m-d(i));
end

end

自 R2024b 起

使用级联传递函数执行零相位滤波。

设计一个椭圆滤波器,通带波纹和阻带衰减分别为 0.1 dB 和 40 dB。指定采样率为 2000 Hz。绘制滤波器的频率响应。

Fs = 2000;
[B,A] = ellip(20,0.1,40,[0.3 0.7],"ctf");
freqz(B,A,2048,Fs,"ctf")

Figure contains 2 axes objects. Axes object 1 with title Phase, xlabel Frequency (kHz), ylabel Phase (degrees) contains an object of type line. Axes object 2 with title Magnitude, xlabel Frequency (kHz), ylabel Magnitude (dB) contains an object of type line.

对线性扫频啁啾信号进行滤波,其中奈奎斯特频率出现在一秒处。比较输入和输出信号的频谱。

t = 0:1/Fs:1;
x = chirp(t,0,t(end),Fs/2)';
y = filtfilt(B,A,x,"ctf");
pspectrum([x y],Fs,Leakage=1,FrequencyResolution=1)

Figure contains an axes object. The axes object with title Fres = 1 Hz, xlabel Frequency (kHz), ylabel Power Spectrum (dB) contains 2 objects of type line.

自 R2024b 起

用传递函数零相位滤波重新生成含噪正弦波伪影。使用 CTF 和尺度值对振荡信号进行滤波。

创建一个由正态分布噪声和三个正弦波形组成的信号 u。采样率为 1 kHz。

rng("default")
Fs = 1e3;
ts = (0:1/Fs:2)';

a0 = [3 2 1];
f0 = [0.1 0.5 0.9]*Fs/2;
p0 = [0 pi/4 pi/2];

u = 0.1*randn(size(ts)) + 0.1*sin(2*pi*f0.*ts+p0)*a0';

通过使用三阶巴特沃斯带阻数字滤波器对 n0 进行滤波,重新生成含噪正弦波伪影,并创建信号 v

[b,a] = butter(3,[0.15 0.85],"stop");
v = filtfilt(b,a,u);

比较 uv。注意两个信号同相。

tiledlayout("flow")
nexttile
strips([u(ts<0.1) v(ts<0.1)],0.1,Fs)
legend(["u" "v"],Location="southeast")
xlabel("Time (seconds)")
nexttile
pspectrum([u v],Fs)
legend(["u" "v"],Location="southeast")

Figure contains 2 axes objects. Axes object 1 with xlabel Time (seconds) contains 2 objects of type line. These objects represent u, v. Axes object 2 with title Fres = 1.2821 Hz, xlabel Frequency (Hz), ylabel Power Spectrum (dB) contains 2 objects of type line. These objects represent u, v.

生成一个电压控制的振荡信号 x。添加由信号 v 表示的含噪正弦波伪影。

vo = exp(-2*abs(ts-1)).*sin(8*pi*ts);
x = vco(vo,[0.25 0.75]*Fs/2,Fs) + v;

用 24 阶切比雪夫 II 型滤波器对信号 x 进行滤波。使用 CTF 格式和尺度值 (B,A,g)。

[B,A,g] = cheby2(24,50,[0.2 0.8],"ctf");
y = filtfilt({B,A,g},x);

比较短时傅里叶变换的幅值平方。观察幅值在阻带处急剧下降。

tiledlayout("flow")
nexttile
stft(x,Fs,Window=bohmanwin(128),OverlapLength=120, ...
    FFTLength=512,FrequencyRange="onesided")
title("Input x")
nexttile
stft(y,Fs,Window=bohmanwin(128),OverlapLength=120, ...
    FFTLength=512,FrequencyRange="onesided")
title("Output y")

Figure contains 2 axes objects. Axes object 1 with title Input x, xlabel Time (s), ylabel Frequency (Hz) contains an object of type image. Axes object 2 with title Output y, xlabel Time (s), ylabel Frequency (Hz) contains an object of type image.

自 R2026a 起

对具有多个谐波的复数值 30 Hz 正弦音应用零相位滤波,谐波间隔为 60 Hz,最高延伸至 600 Hz。

创建一个采样率为 600 Hz 的两秒复数值信号。该信号包含一个 10 V 30 Hz 正弦音,并具有 10 个谐波,频率从 60 Hz 到 600 Hz 均匀分布,振幅各为 1 V。

Fs = 600;
t = (0:1/Fs:2)';
x = 10*exp(1i*2*pi*30*t) + sum(exp(1i*2*pi*60*t*(0:9)),2);

由于音调在 30 Hz 处振荡,而不需要的分量在每隔 60 Hz 直到第十个倍频处有频率峰值,因此一个 10 阶 IIR 梳状陷波滤波器适用于还原音调,即感兴趣的信号。

ba 定义为表示 10 阶 IIR 梳状陷波滤波器的分子系数和分母系数的向量,该滤波器的质量因子为 35。要了解有关设计具有特定阶数和质量因子的 IIR 梳状滤波器的更多信息,请参阅 iircomb (DSP System Toolbox)

b = [0.957 zeros(1,9) -0.957];
a = [1 zeros(1,9) -0.914];

绘制从 0.9 到 1.1 秒的信号的实部。绘制从 0 到 600 Hz 的滤波器响应。

tiledlayout("flow")
nexttile
plot(t,real(x))
xlim([0.9 1.1])
xlabel("Time (s)")
title("real(x)")
nexttile
[h,f] = freqz(b,a,8192,"whole",Fs);
plot(f,mag2db(abs(h)))
xlabel("Frequency (Hz)")
title("Magnitude Response (b,a)")

Figure contains 2 axes objects. Axes object 1 with title real(x), xlabel Time (s) contains an object of type line. Axes object 2 with title Magnitude Response (b,a), xlabel Frequency (Hz) contains an object of type line.

对输入信号进行滤波,同时保留相位。使用古斯塔夫森方法估计滤波器状态的初始条件。假设瞬变长度等于信号长度,并通过镜像采样来填充输入信号。

y = filtfilt(b,a,x, ...
    InitialStatesMethod="gustafsson", ...
    TransientLength=length(x), ...
    PaddingPattern="reflect");

比较时域和频域中的输入信号和滤波信号。绘制从 0.9 到 1.1 秒的两个信号的实部,以及从 0 到 600 Hz 的韦尔奇功率谱。滤波后的信号显示去除了谐波的 30 Hz 音调,同时滤波后的信号 y 与输入信号 x 同相。

figure;
tiledlayout("vertical")
nexttile
plot(t,real(x),t,real(y),"--")
legend("real(" + ["x" "y"] +")",Location="southeast")
xlabel("Time (s)")
xlim([0.9 1.1])
nexttile
[p,f] = pwelch([x y],[],[],8192,Fs);
pdb = pow2db(abs(p));
plot(f,pdb(:,1),"-",f,pdb(:,2),"--")
xlabel("Frequency (Hz)")
legend("PSD of " + ["x" "y"],Location="southeast")

Figure contains 2 axes objects. Axes object 1 with xlabel Time (s) contains 2 objects of type line. These objects represent real(x), real(y). Axes object 2 with xlabel Frequency (Hz) contains 2 objects of type line. These objects represent PSD of x, PSD of y.

输入参数

全部折叠

传递函数系数,指定为向量。如果使用全极点滤波器,请将 b 设置为 1。如果使用全零点 (FIR) 滤波器,请将 a 设置为 1

示例: b = [1 3 3 1]/6a = [3 0 1 0]/3 用于指定一个归一化 3 dB 频率为 0.5π 弧度/采样点的三阶巴特沃斯滤波器。

数据类型: double | single

输入信号,指定为实数值或复数值向量、矩阵或 N 维数组。x 包含的值必须为有限值。x 的长度必须大于滤波器阶数的三倍,定义为 max(length(B)-1, length(A)-1)。除非 x 是行向量,否则该函数沿 x 的第一个数组维度进行运算。如果 x 是行向量,则该函数沿第二个维度进行运算。

示例: cos(pi/4*(0:159))+randn(1,160) 是单通道行向量信号。

示例: cos(pi./[4;2]*(0:159))'+randn(160,2) 是双通道信号。

数据类型: double | single
复数支持:

二阶节系数,指定为矩阵。sos 是一个 L×6 矩阵,其中节数 L 必须大于或等于 2。如果节数小于 2,则该函数将输入视为分子向量。sos 的每行对应于二阶 (biquad) 滤波器的系数。sos 的第 i 行对应于 [bi(1) bi(2) bi(3) ai(1) ai(2) ai(3)]

示例: s = [2 4 2 6 0 2;3 3 0 6 0 0] 用于指定一个归一化 3 dB 频率为 0.5π 弧度/采样点的三阶巴特沃斯滤波器。

数据类型: double | single

尺度值,指定为具有 L + 1 个元素的实数值标量或实数值向量,其中 L 是 CTF 节的数量。尺度值表示滤波器增益在级联滤波器表示的各节之间的分布。

filtfilt 函数使用 scaleFilterSections 函数将增益应用于滤波器节,具体取决于您如何指定 g

  • 标量 - 函数将增益均匀分布在所有滤波器节上。

  • 向量 - 函数将前 L 个增益值应用于对应的滤波器节,并将最后一个增益值均匀分布在所有滤波器节上。

数据类型: double | single

数字滤波器,指定为 digitalFilter 对象。使用 designfilt 根据频率响应设定生成数字滤波器。

示例: d = designfilt("lowpassiir",FilterOrder=3,HalfPowerFrequency=0.5) 用于指定一个归一化 3 dB 频率为 0.5π 弧度/采样点的三阶巴特沃斯滤波器。

级联传递函数 (CTF) 系数,指定为标量、向量或矩阵。BA 分别列出级联传递函数的分子系数和分母系数。

B 的大小必须为 L×(m + 1),A 的大小必须为 L×(n + 1),其中:

  • L 表示滤波器节的数量。

  • m 表示滤波器分子的阶。

  • n 表示滤波器分母的阶。

有关级联传递函数格式和系数矩阵的详细信息,请参阅以 CTF 格式指定数字滤波器

注意

如果 A(:,1) 的任一元素不等于 1,则 filtfiltA(:,1) 对滤波器系数进行归一化。在这种情况下,A(:,1) 必须为非零。

示例: B = [2 4 2;3 3 0]A = [6 0 2;6 0 0] 用于指定归一化 3 dB 频率为 0.5π 弧度/采样点的三阶巴特沃斯滤波器。

数据类型: double | single
复数支持:

名称-值参数

全部折叠

将可选参量对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参量名称,Value 是对应的值。名称-值参量必须出现在其他参量之后,但对各个参量对组的顺序没有要求。

示例: y = filtfilt(d,x,InitialStatesMethod="gustafsson") 使用数字对象 d 对输入信号 x 进行零相位滤波,并应用古斯塔夫森的前向-后向最小二乘方法来计算最优初始状态。

自 R2026a 起

估计滤波器状态的初始条件(初始状态)的方法,指定为以下项之一:

  • "const" - filtfilt 通过求解从滤波器系数派生的线性系统来估计初始状态。

    • 此方法假设一个常量输入信号和一个处于稳态运行的系统。因此,滤波后的信号从对应于常量输入信号的稳态值开始。

    • 如果 x 不是常量,则该函数使用其第一个采样来假定一个常量输入信号来使用此方法。

  • "gustafsson" - filtfilt 使用古斯塔夫森的前向-后向最小二乘方法估计初始状态 [1]。此方法最小化前向-后向和后向-前向滤波输出之间差异的能量,从而实现对称性并减少两端的边界伪影。

  • "zero" - filtfilt 将所有初始状态都设置为零。此方法的计算复杂度最低,并且与输入信号或滤波器响应无关。

自 R2026a 起

瞬态响应的长度(瞬变长度),指定为 "filtord""stepzlen" 或小于或等于 length(x) 的非负整数。

瞬态长度表示 filtfilt 用于建模和隐藏滤波信号开始和结束处瞬态响应的采样数。

  • "filtord" - filtfilt 使用三倍滤波器阶数的瞬态长度。

  • "stepzlen" - filtfilt 使用基于滤波器阶跃响应的稳定时间的瞬态长度。

    对于具有阶跃响应 s[k] 和稳态值 sfinal 的滤波器,该函数将瞬态长度确定为满足 |s[k] – sfinal| < 0.02×max(|s[k] – sfinal|) 的最小索引 k

    如果 k 大于信号长度,则该函数使用信号长度 length(x) 作为瞬态长度。

  • 小于或等于 length(x) 的非负整数 - filtfilt 使用指定的瞬态长度。

如果您将 PaddingPatern 指定为 "none",则 filtfilt 会忽略您在 TransientLength 中指定的值,并假定没有要建模或从滤波信号中隐藏的瞬态响应。

自 R2026a 起

滤波前填充输入信号的模式,指定为 "linear""reflect""none"

该函数使用您在 TransientLength 中指定的值来确定沿其工作维度填充输入信号 x 的采样数。该函数使用填充的采样来建模,并在返回 y 之前从滤波信号的两端隐藏建模的瞬态响应。

下表列出了模式名称及其描述,以及每种模式如何填充输入数据 x = [a b c d ... j k l m] 的示例。

填充模式描述填充后的数据
"linear"

该函数在两端填充输入信号,以保持边界处的斜率连续性。

这种填充模式确保信号平滑地延续到过渡区域,并有助于隐藏边界瞬态响应。

"reflect"该函数通过在每端镜像采样(不复制端点)来填充输入信号。

"none"

该函数不填充输入信号。

在这种情况下,filtfilt 也会忽略在 TransientLength 中指定的值。

输出参量

全部折叠

滤波后的信号,以向量、矩阵或 N 维数组形式返回。

  • filtfilt 函数返回与 x 大小相同的 y

  • 如果将任一输入参量指定为 single 类型,则 filtfilt 使用单精度算术执行滤波运算,并以 y 类型返回 single。否则,filtfilt 返回类型为 doubley

详细信息

全部折叠

提示

您可以获得 CTF 格式的滤波器,包括缩放增益。使用数字 IIR 滤波器设计函数的输出,例如 buttercheby1cheby2ellip。在这些函数中指定 "ctf" 滤波器类型参量,并指定返回 BAg 以获取尺度值。 (自 R2024b 起)

参考

[1] Gustafsson, F. “Determining the initial states in forward-backward filtering.” IEEE® Transactions on Signal Processing. Vol. 44, April 1996, pp. 988–992. https://doi.org/10.1109/78.492552.

[2] Lyons, Richard G. Understanding Digital Signal Processing. Upper Saddle River, NJ: Prentice Hall, 2004.

[3] Mitra, Sanjit K. Digital Signal Processing. 2nd Ed. New York: McGraw-Hill, 2001.

[4] Oppenheim, Alan V., and Ronald W. Schafer, with John R. Buck. Discrete-Time Signal Processing. 2nd Ed. Upper Saddle River, NJ: Prentice Hall, 1999.

扩展功能

全部展开

版本历史记录

在 R2006a 之前推出

全部展开