补偿滤波器引入的延迟和失真
对信号进行滤波会引入延迟。这意味着相对于输入,输出信号在时间上有所偏移。
当偏移不变时,您可以通过按时间偏移信号来校正延迟。
有时滤波器延迟各频率分量的时间是不相等的。这种现象称为相位失真。为了补偿这种影响,您可以使用 filtfilt
函数执行零相位滤波。
以 500 Hz 的频率对心电图读数采样,采样时间为 1 秒。添加随机噪声。重置随机数生成器以获得可重现的结果
Fs = 500;
N = 500;
rng default
xn = ecg(N)+0.1*randn([1 N]);
tn = (0:N-1)/Fs;
使用滤波器阻挡高于 75 Hz 的频率,以消除部分噪声。使用 designfilt
设计一个 70 阶 FIR 滤波器。
Nfir = 70; Fst = 75; firf = designfilt('lowpassfir','FilterOrder',Nfir, ... 'CutoffFrequency',Fst,'SampleRate',Fs);
对信号进行滤波并绘图。与原始信号相比,结果更平滑,但存在滞后。
xf = filter(firf,xn); plot(tn,xn,tn,xf) title 'Electrocardiogram' xlabel 'Time (s)' legend('Original','FIR Filtered') grid
使用 grpdelay
检查滤波器造成的延迟是否等于滤波器阶数的一半。
grpdelay(firf,N,Fs)
delay = mean(grpdelay(firf))
delay = 35
对齐数据。通过删除前 delay
个采样来移动滤波后的信号。删除原始采样和时间向量的最后 delay
个采样。
tt = tn(1:end-delay); sn = xn(1:end-delay); sf = xf; sf(1:delay) = [];
对信号绘图,并验证它们是否对齐。
plot(tt,sn,tt,sf) title 'Electrocardiogram' xlabel('Time (s)') legend('Original Signal','Filtered Shifted Signal') grid
使用一个 7 阶 IIR 滤波器重复计算。
Niir = 7; iir = designfilt('lowpassiir','FilterOrder',Niir, ... 'HalfPowerFrequency',Fst,'SampleRate',Fs);
对信号进行滤波。滤波后的信号比原始信号干净,但相对于原始信号存在滞后。由于滤波器的非线性相位,它也存在失真。
xfilter = filter(iir,xn); plot(tn,xn,tn,xfilter) title 'Electrocardiogram' xlabel 'Time (s)' legend('Original','Filtered') axis([0.25 0.55 -1 1.5]) grid
通过观察滤波器引入的群延迟,可以看出延迟与频率有关。
grpdelay(iir,N,Fs)
使用 filtfilt
对信号进行滤波。延迟和失真已被有效消除。当使信号的相位信息保持原样至关重要时,请使用 filtfilt
。
xfiltfilt = filtfilt(iir,xn); plot(tn,xn) hold on plot(tn,xfilter) plot(tn,xfiltfilt) title 'Electrocardiogram' xlabel 'Time (s)' legend('Original','''filter''','''filtfilt''') axis([0.25 0.55 -1 1.5]) grid