Sort a bank of ECG samples to 2 groups
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Portalboi
el 6 de En. de 2023
Comentada: Star Strider
el 11 de En. de 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 comentarios
Respuesta aceptada
Star Strider
el 8 de En. de 2023
Editada: Star Strider
el 8 de En. de 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 comentarios
Star Strider
el 11 de En. de 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.
Más respuestas (1)
Vilém Frynta
el 6 de En. de 2023
Editada: Vilém Frynta
el 6 de En. de 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 comentarios
Ver también
Categorías
Más información sobre ECG / EKG 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!