Компенсируйте задержку и искажение, введенное фильтрами

Фильтрация сигнала вводит задержку. Это означает, что выходной сигнал переключен вовремя относительно входа.

Когда сдвиг является постоянным, можно исправить для задержки путем сдвига сигнала вовремя.

Иногда фильтр задерживает некоторые частотные составляющие больше, чем другие. Это явление называется искажением фазы. Чтобы компенсировать этот эффект, можно выполнить фильтрацию нулевой фазы с помощью функции filtfilt.

Снимите показания электрокардиограммы, выбранные на уровне 500 Гц в течение 1 с. Добавьте случайный шум. Сбросьте генератор случайных чисел для восстанавливаемых результатов

Fs = 500;
N = 500;

rng default

xn = ecg(N)+0.1*randn([1 N]);
tn = (0:N-1)/Fs;

Удалите часть шума с помощью фильтра, который останавливает частоты выше 75 Гц. Используйте designfilt, чтобы разработать КИХ-фильтр порядка 70.

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-го порядка.

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