Need help to removing motion artifact from ECG signal

Hello Expert,
I have 4 channel ECG signal. Ecg is recored while the person is walking. So ECG have motion artifact. I need your advice..
1-Which filter use to remove motion artifact from the signal?
2- How to campare filtered and unfiltered signal?
Please see the attached data file.
I am looking positive for your reponse.
Take care

 Accepted Answer

Try something like this —
LD = load('test10_00wm.mat')
LD = struct with fields:
val: [4×4000 double]
type('ECG.m') % I was hoping That The 'ECG.m' File Had A Sampling Frequency
ECG = val';
val = LD.val.'; % Transpose
Fs = 1;
L = size(val,1);
t = linspace(0, L-1, L)/Fs;
figure
tiledlayout(size(val,2),1)
for k = 1:size(val,2)
nexttile
plot(t, val(:,k))
grid
end
sgtitle('Original')
xlabel('Time (units)')
Fn = Fs/2;
NFFT = 2^nextpow2(L);
FTval = fft((val-mean(val)).*hann(L), NFFT)/L;
Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
figure
tiledlayout(size(val,2),1)
for k = 1:size(val,2)
nexttile
plot(Fv, abs(FTval(Iv,k))*2)
grid
xlim([0 Fs*0.1])
end
xlabel('Frequency (cycles/(time unit))')
val_filt = highpass(val, 0.001*Fs, Fs, 'ImpulseResponse','iir');
figure
tiledlayout(size(val,2),1)
for k = 1:size(val_filt,2)
nexttile
plot(t, val(:,k))
grid
end
sgtitle('Filtered')
xlabel('Time (units)')
figure
tiledlayout(size(val,2),1)
for k = 1:size(val_filt,2)
nexttile
plot(t, val(:,k))
grid
xlim([0 1000])
end
sgtitle('Filtered (Detail)')
xlabel('Time (units)')
The isoelectric reference in an EKG recording is defined as the value of the P-R interval. By that standard, there is not much baseline drift in columns 2-4, however a highpass filter eliminates what llitle baseline drift there may be.
The rhythm in all appears to be regular, however without an accurate time base, I cannot estimate the rate or measure the intervals. I assume normal sinus rhythim in all the columns, however I cannot see the P-deflections in any of them. Column 1 appears to be bad lead placement, although I cannot rule out significant pathology (possibly hyperkalemia, however a clinical correlation would be necessary). Columns 2 & 3 appear to be normal, although the P deflection appears to be absent in both and the T-deflection also absent in column 3. Column 4 has what appears to be significant S-T depression, likely due to ischaemia, although drug effects cannot be ruled out.
Clinical Impression: Column 1 needs to be re-recorded, column 4 could have significant pathology and needs urgent clinical follow-up.
.

11 Comments

Hello Star,
Woow you are great :)
What I write in the title of figure 2?
What is the difference between filter and filtered Detail graphs?
Can you more explain Figure 2,3,4 more?
Thanks for your prompt support.
As always, my pleasure!
Thank you!
The second figure are the Fourier transforms of the unfiltered signals. The frequency axis is labeled. The y-axis in each instance are the magnitudes of the signals.
The ‘Filtered (Detail)’ are simply the ‘Filtered’ data enlarged on the x (Time) axis to show detail of the first three complexes.
Hey Star,
I dont find the difference between figure 1 and 3. Is figure 3 is important?
Hey Star,
I have 3 question for you yet.
1- I change the limit of figure 4 (0 to 4000) .Figure 4 seem same as figure 1. How we can see the difference between original and filtered signal.
2- Please give your obbservation regarding the attached signal after filtering.
I am looking for your positive response.
There are differences, however they are subtle. You can see that if you subtract the filtered data from the original data.
LD = load('test11_45wm.mat')
LD = struct with fields:
val: [4×4000 double]
% type('ECG.m') % I was hoping That The 'ECG.m' File Had A Sampling Frequency
val = LD.val.'; % Transpose
Fs = 1;
L = size(val,1);
t = linspace(0, L-1, L)/Fs;
figure
tiledlayout(size(val,2),1)
for k = 1:size(val,2)
nexttile
plot(t, val(:,k))
grid
end
sgtitle('Original')
xlabel('Time (units)')
Fn = Fs/2;
NFFT = 2^nextpow2(L);
FTval = fft((val-mean(val)).*hann(L), NFFT)/L;
Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
figure
tiledlayout(size(val,2),1)
for k = 1:size(val,2)
nexttile
plot(Fv, abs(FTval(Iv,k))*2)
grid
xlim([0 Fs*0.1])
end
xlabel('Frequency (cycles/(time unit))')
val_filt = highpass(val, 0.0025*Fs, Fs, 'ImpulseResponse','iir');
figure
tiledlayout(size(val,2),1)
for k = 1:size(val_filt,2)
nexttile
plot(t, val(:,k))
grid
end
sgtitle('Filtered')
xlabel('Time (units)')
figure
tiledlayout(size(val,2),1)
for k = 1:size(val_filt,2)
nexttile
plot(t, val(:,k))
grid
xlim([0 1000])
end
sgtitle('Filtered (Detail)')
xlabel('Time (units)')
The frequency chatracteristics are different, so the filter now removes a slightly larger frequency range than in the earlier set. (There is not much baseline drift in any of the records.) This accounts for the baseline variation principally in the last EKG trace. Records 1 & 4 in the earlier file now appear to be 4 & 3 (respectively) in this file. My clinical impression remains the same.
.
Thanks Star
:)
As always, my pleasure!
Hey Expert
Star, I need your clinical obervatio on the attached result.
Please give your reviews.
Thanks
They are all noisy, contaminated both with low-frequency baseline variation and possibly mains (line) noise (50 Hz - 60 Hz).
The first one appears to be normal with a normal rhythm.
The second one is so corrupted by low-frequency (apparently random) noise, that I can’t even estimate the rhythm.
The third one isn’t any better. I can’t even reliably detect QRS complexes.
The fourth one has some baselilne variation and line noise, however I can see no significant pathology. The intervals all appear to have the correct relative relationships, however without a reliable time base, I can’t estimate a rate.
It is important to always use a neutral reference (a right leg lead, commonly but erroneously called a ‘ground’) to eliminate as much baselilne noise and mains frequency noise as possible. Subtract that signal from all the other leads using a differential amplifier to considerably improve the recordings.
thanks star

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!