Sort a bank of ECG samples to 2 groups
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Portalboi
am 6 Jan. 2023
Kommentiert: Star Strider
am 11 Jan. 2023
Hey,
I've a bank of 2 types of ECG samples: link, some of them were measured while exercising and some while resting
all the samples are 5 seconds long, and were measured at 1k[Hz] frequency
I'm having a hard time develop an algorithem to sort that bank to 2 groups (exercising and resting)
any ideas?
3 Kommentare
Akzeptierte Antwort
Star Strider
am 8 Jan. 2023
Bearbeitet: Star Strider
am 8 Jan. 2023
This is the best I can do for these.
They required a significant amount of processing to remove the baseline variation and high-frequency noise. (The processing uses two filters, the first a notch filter to remove the 50 Hz line noise, and the second bandpass filter to eliminate baseline variation and high frequency noise. The detrend call removes any baseline variation left after filtering.) The ‘Before’ and ‘After’ plots are displayed for the first 20. The table at the end displays the rate and voltage for each filtered EKG. Some of them (for example #5 and #20) are so noisy that it is difficult to do anything with them. The noise can simply swamp the data, and it is difficult to do anything about that.
Of note, #2, #4, #14 and #18 display a strain pattern (significant S-T depression) that I find worrisome.
I’m not certain how best to classify them. There can be significant uncertainty since there can be individual variation that can make that difficult. It would be easier to classify the data for a single subject between rest and exercise than for all subjects.
Uz1 = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1254867/DataECG600Shorted.zip')
% Uz2 = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1254872/DataECG600Shorted.zip')
Fs = 1E+3;
Fn = Fs/2;
L = 5001;
t = linspace(0, L-1, L).'/Fs;
N = 20;
for k = 1:N%numel(Uz1)
LD = load(Uz1{k});
EKG1(:,k) = LD.thisSignal;
end
Wp = [45 55]/Fn; % Passband Frequency (Normalised)
Ws = [48 52]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple
Rs = 60; % Passband Ripple (Attenuation)
[n,Wp] = ellipord(Wp,Ws,Rp,Rs); % Elliptic Order Calculation
[z,p,k] = ellip(n,Rp,Rs,Wp,'stop'); % Elliptic Filter Design: Zero-Pole-Gain
[sos1,g1] = zp2sos(z,p,k); % Second-Order Section For Stability
figure
freqz(sos1, 2^16, Fs) % Filter Bode Plot
Wp = [0.20 60]/Fn; % Passband Frequency (Normalised)
Ws = [0.10 65]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple
Rs = 60; % Passband Ripple (Attenuation)
[n,Wp] = ellipord(Wp,Ws,Rp,Rs); % Elliptic Order Calculation
[z,p,k] = ellip(n,Rp,Rs,Wp); % Elliptic Filter Design: Zero-Pole-Gain
[sos2,g2] = zp2sos(z,p,k); % Second-Order Section For Stability
figure
freqz(sos2, 2^16, Fs) % Filter Bode Plot
figure
for k = 1:N
subplot(N/5,5,k)
plot(t, EKG1(:,k))
grid
title(sprintf('%3d',k))
end
sgtitle('Original')
NFFT = 2^nextpow2(L);
Fv = linspace(0, 1, NFFT/2+1)*Fn
Iv = 1:numel(Fv);
for k = 1:N
FTEKG1(:,k) = fft(EKG1(:,k)-mean(EKG1(:,k)),NFFT)/L;
end
% NrSp = size(EKG1,2);
figure
for k = 1:N
subplot(N/5,5,k)
plot(Fv, abs(FTEKG1(Iv,k))*2)
grid
xlim([00 60])
title(sprintf('EKG1 %3d',k))
end
for k = 1:size(EKG1,2)
EKG1(:,k) = filtfilt(sos1,g1,EKG1(:,k));
EKG1(:,k) = filtfilt(sos2,g2,EKG1(:,k));
EKG1(:,k) = detrend(EKG1(:,k),7);
end
figure
for k = 1:N
subplot(N/5,5,k)
plot(t, EKG1(:,k))
grid
[pks,locs] = findpeaks(EKG1(:,k), 'MinPeakProminence',(max(EKG1(:,k)))*0.75);
Ratev = 60./(diff(t(locs)));
Rate(k,:) = mean(Ratev);
RateSD(k,:) = std(Ratev);
V(k,:) = mean(pks);
VSD(k,:) = std(pks);
title(sprintf('EKG1 %3d',k))
end
sgtitle('Filtered')
EKG1_Nr = (1:N).';
RateVoltage = table(EKG1_Nr,Rate,RateSD,V,VSD)
EDIT — (8 Jan 2023 at 11:54)
Added ‘RateSD’ and ‘VSD’ to calculations and to the table. Code otherwise unchanged.
.
2 Kommentare
Star Strider
am 11 Jan. 2023
As always, my pleasure!
The standard deviation (specifically ‘coefficient of variation’, defined as the standard deviation divided by the mean) can be helpful is assessing the quality of the data. The larger it is, the less reliable the data are.
Weitere Antworten (1)
Vilém Frynta
am 6 Jan. 2023
Bearbeitet: Vilém Frynta
am 6 Jan. 2023
Hello,
as Star Strider already mentioned, you can filter data based on the R-amplitude and or heart rate (time between R–R).
I have tried to plot your data and it seems there is quite a big difference in amplitudes, so it appears that it could be a reliable filter.
Also, I am not very confident whether this is valid option, but I tried to perform FFT on your data, and it looks like there might be a difference between resting ECG and excersing ECG. But it is possible that I have chosen some data that are "perfect" and this might not be the case for the rest of your data.
See images below;
== example 1 and it's FFT ==
== example 2 and it's FFT ==
0 Kommentare
Siehe auch
Kategorien
Mehr zu ECG / EKG finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!