在信号处理中,巴特沃斯滤波器用于数字滤波器时,一般是iir滤波器,这种滤波器一般会产生相移。
filtfilt实现零相位滤波(Zero-phase Filtering)。它通过对信号进行正向和反向两次滤波,消除了滤波过程中的相位延迟,使得滤波后的信号保持原始相位。filtfilt的输出信号幅度会因为两次滤波而变为原滤波器幅度响应的平方,尽管它确保了信号的相位没有变化。
举一个巴特沃斯滤波器用于零相位滤波器的MATLAB例子。冈萨雷斯那种对幅值采样直接用的方法,很离谱。
Zero-Phase Filtering of an Electrocardiogram Waveform
Zero-phase filtering helps preserve features in a filtered time waveform exactly where they occur in the unfiltered signal.
Zero-phase filter a synthetic electrocardiogram (ECG) waveform. The function that generates the waveform is at the end of the example. The QRS complex is an important feature in the ECG. Here it begins around time point 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")
Corrupt the ECG with additive noise. Reset the random number generator for reproducible results. Construct a lowpass FIR equiripple filter and filter the noisy waveform using both zero-phase and conventional filtering.
rng default
x = wform' + 0.1*randn(500,1);
Zero-phase filtering reduces noise in the signal and preserves the QRS complex at the same time it occurs in the original. Conventional filtering reduces noise in the signal, but delays the QRS complex.
Repeat the filtering using a Butterworth second-order section filter.
[b,a] = butter(12,0.15);
y = filtfilt(b,a,x);
subplot(1,1,1)
plot(x)
hold on
plot(y,LineWidth=3)
legend("Noisy ECG","Zero-Phase Filtering")
y1 = filter(b,a,x);
figure
plot([y y1])
title("Filtered Waveforms")
legend(["Zero-phase Filtering" "Conventional Filtering"])
比较
This function generates the ECG waveform.
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