How to get rid of ringing/overshoot in an ecg signal while using notch filter?
10 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Stephan Lallinger
el 4 de Nov. de 2019
Comentada: Daniel M
el 6 de Nov. de 2019
Hallo all,
i have an ecg signal which contains 50 Hz noise. I want to get rid off the noise.
First of all i do a pre processing step with a highpass and lowpass and. After this i use the notch filter.
Notch filter code:
f_noise = 50; %noise to filter
fs = 500;
f_notch = f_noise/fs; %normalized noise
N =[exp(j*2*pi*f_notch);exp(-j*2*pi*f_notch)]; %place zeros
P = 0.5*N; %place additional poles with same angular as zeros
b = poly(N); a = poly(P); %get filter coeff.
Problem here i got an "overshoot" in the QRS complex (see Picture).
A other member suggested this notch filter to implement:
%Notchfilter by Daniel. M
Fs = 500;
Fn = fs/2; % Nyquist frequency
numHarmonics = 0; % Let's do 50, 100, 150, 200, 250; 0 -> filter only 50 Hz
lineFreq = 50; % Hz
for fq = ((0:numHarmonics)+1) * lineFreq
Fl = fq + [-1, 1]; % notch around Fl. Could try [-2, 2] if too tight
[z,p,k] = butter(1, Fl/Fn, 'stop');
sos = zp2sos(z,p,k);
ecg_signal_005_150_notch = filtfilt(sos, 1, ecg_signal_005_150); % assumes data is [time x ... dimensions]
% overwrites data, and filters sequentially for each notch
end
This solution removes the "overshoot" perfectly but it adds "ringing" (see picture).
Does somebody know a good trade-off between ringing and overshoot?
Best regards
1 comentario
Respuesta aceptada
Daniel M
el 4 de Nov. de 2019
Editada: Daniel M
el 4 de Nov. de 2019
clearvars
clc
close all
fs = 500;
ecg = xlsread('Noisy_50HZ_ECG.xlsx');
ecg = detrend(ecg.');
ecg = sgolayfilt(ecg,0,5);
T = 1/fs;
L = length(ecg);
t = (0:L-1)*T;
filtfreq = [0.5 40];
xlim = [49 51];
%%%% Apply my own filters
[B,A] = butter(4, filtfreq./(fs/2));
f_ecg = filtfilt(B,A,ecg);
%%% Notch filter
data = f_ecg;
Fn = fs/2; % Nyquist frequency
numHarmonics = 3; % Let's do 50, 100, 150, 200
lineFreq = 50; % Hz
for fq = ((0:numHarmonics)+1) * lineFreq
Fl = fq + [-1, 1];
[z,p,k] = butter(6, Fl/Fn, 'stop');
sos = zp2sos(z,p,k);
data = filtfilt(sos, 1, data);
end
figure
plot(t,ecg,'b.-',t,data,'r-')
set(gca,'XLim',[48 52])
figure
plot(t,data)
set(gca,'XLim',[49 51])
I also tried an FIR notch, using the fieldtrip toolbox, different bandpasses, etc. But this is what I think worked best.
(Reading the data from https://www.mathworks.com/matlabcentral/answers/487640-ecg-spectrum-wrong#comment_762871)
4 comentarios
Stephan Lallinger
el 6 de Nov. de 2019
Editada: Stephan Lallinger
el 6 de Nov. de 2019
Daniel M
el 6 de Nov. de 2019
It makes sense that it would work well with a "perfect" 50 Hz noise signal. But real world applications are not so ideal, as you have learned.
If you eventually find a solution that works well for you, please post here for myself and others to learn from. Good luck!
Más respuestas (0)
Ver también
Categorías
Más información sobre Single-Rate Filters en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!