How to upsample an ECG signal and its associated data?

I have an ECG signal which has a sampling frequency of 250 Hz and I want to upsample it to 360 Hz.
The signal has peaks and the indexes of the peaks are also given as "peaks.mat".
The given data is described as follows:
sig.mat: ECG signal whose size is 273010X1, which has 633 peaks as specified in "peaks.mat".
peaks.mat: the sample index where the peaks occur in "sig.mat" and the size is 633X1
So, besides upsampling the signal, how to adjust the indexes of the peaks accordingly?
Thank you,

Réponses (2)

Star Strider
Star Strider le 23 Juin 2024

0 votes

Use the resample function to upsample it, since this function is specifically designed for signal processing, and contains an anti-aliasing filter to prevernt spurious frequencies from appearing in the resampled signal.

6 commentaires

My pleasure.
Tey should not need any adjusting. The P, R, and T deflections (‘peaks’) should be at essentially the same times they were in the original trace, and the intervals should not change significantly. The times may differ slightly because the time vector is different, however they should be close. The amplitudes should also be essentially the same.
I did not see the .mat file originally, so it must have been added later. (The informattion says that it was added about an hour ago.)
LD = load('dataUpsampling.mat')
LD = struct with fields:
peaks: [633x1 double] sig: [273010x1 double]
The problem here is that we need to have a time vector that should have been supplied with the original EKG data. I can go no further without it.
If the time vector and the original EKG trace that uses it appear, I will proceed with my analysis.
.
I do need to know the time! I cannot proceed without it.
Your ‘peaks’ are what I would consider ‘locs’ (indices) in the usual findpeaks terminology.
It is likely not appropriate to use tthe original peak values and locations on a resampled signal. Recalculate everything on the resampled signal instead.
Illustration, with a possible solution —
LD = load('dataUpsampleTime.mat')
LD = struct with fields:
peaks: [2273x1 double] sig: [650000x1 double] tm: [650000x1 double]
peaks = LD.peaks
peaks = 2273x1
77 370 662 946 1231 1515 1809 2044 2402 2706
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
sig = LD.sig;
tm = LD.tm;
Ts = mean(diff(tm))
Ts = 0.0028
% Tsd = std(diff(tm))
Fs = 1/Ts
Fs = 360.0000
[myPks,myLocs] = findpeaks(sig, 'MinPeakProminence',0.5)
myPks = 2274x1
0.8400 0.9400 0.9600 0.8600 0.8200 0.8850 0.9450 0.8750 0.8850 0.8900
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
myLocs = 2274x1
78 371 664 948 1232 1516 1810 2046 2404 2707
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
figure
plot(tm, sig)
hold on
plot(tm(peaks), sig(peaks), 'vr')
plot(tm(myLocs), myPks, '^g')
hold off
grid
xlim([0 25])
sig_filt = highpass(sig, 1.5, Fs, 'ImpulseResponse','iir'); % Filter Out Baseline Variation
[myPks_filt,myLocs_filt] = findpeaks(sig_filt, 'MinPeakProminence',0.5)
myPks_filt = 2275x1
1.0716 1.2052 1.2409 1.1596 1.1284 1.1793 1.2195 1.1486 1.2068 1.1880
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
myLocs_filt = 2275x1
78 371 664 948 1232 1516 1810 2046 2404 2707
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
figure
plot(tm, sig_filt)
hold on
plot(tm(peaks), sig_filt(peaks), 'vr')
plot(tm(myLocs_filt), myPks_filt, '^g')
hold off
grid
xlim([0 25])
I would go back and re-calculate the peak locations and peak values on the resampled signal, as I have done here. Then, use those. (Keep or remove the baseline variation. I provided an approach for tthat if you want to use it.)
.
What are you intending to demonstrate here?
My suggestion remains that the best approach is to get the peaks and indices of the upsampled signal after upsampling it. There is really no poiint to getting those datta from the original signal and then upsampling it, then upsampling or interpolating the peaks and locations to the upsampled signal.
Just do everythiung once on the upsampled signal and be done with it.
Mibang
Mibang le 24 Juin 2024
Modifié(e) : Mibang le 24 Juin 2024
Thank you, but your approach is not what I want.
I think I got your helpl enough. Thank you.
My pleasure!
What do you want, then?
I’m still not clear on that.
% LD = load('dataUpsampleTime.mat')
file = websave('dataUpsampleTime.mat','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1721431/dataUpsampleTime.mat');
LD = load(file);
peaks = LD.peaks
peaks = 2273x1
77 370 662 946 1231 1515 1809 2044 2402 2706
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
sig = LD.sig;
tm = LD.tm;
Ts = mean(diff(tm))
Ts = 0.0028
% Tsd = std(diff(tm))
Fs = 1/Ts
Fs = 360.0000
[myPks,myLocs] = findpeaks(sig, 'MinPeakProminence',0.5)
myPks = 2274x1
0.8400 0.9400 0.9600 0.8600 0.8200 0.8850 0.9450 0.8750 0.8850 0.8900
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
myLocs = 2274x1
78 371 664 948 1232 1516 1810 2046 2404 2707
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
figure
plot(tm, sig)
hold on
plot(tm(peaks), sig(peaks), 'vr')
plot(tm(myLocs), myPks, '^g')
hold off
grid
xlim([0 25])
sig_filt = highpass(sig, 1.5, Fs, 'ImpulseResponse','iir'); % Filter Out Baseline Variation
[myPks_filt,myLocs_filt] = findpeaks(sig_filt, 'MinPeakProminence',0.5);
figure
plot(tm, sig_filt)
hold on
plot(tm(peaks), sig_filt(peaks), 'vr')
plot(tm(myLocs_filt), myPks_filt, '^g')
hold off
grid
xlim([0 25])
[sig450,t450] = resample(sig_filt,tm,450)
sig450 = 812500x1
0.0093 0.0105 0.0107 0.0116 0.0128 0.0133 0.0134 0.0169 0.0125 0.0213
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
t450 = 812500x1
0 0.0022 0.0044 0.0067 0.0089 0.0111 0.0133 0.0156 0.0178 0.0200
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
format shortG
myLocs450 = resample(myLocs, 360,450)
myLocs450 = 1820x1
1.0e+00 * 84.705 441.23 809.46 1155.2 1523.7 1858.6 2219.1 2640.5 2994 3354.2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
myLocs450 = round(myLocs450)
myLocs450 = 1820x1
85 441 809 1155 1524 1859 2219 2640 2994 3354
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
[MyPks450,MyLocs450] = findpeaks(sig450, 'MinPeakProminence',0.5)
MyPks450 = 2275x1
1.0691 1.2059 1.2364 1.1561 1.1356 1.1777 1.2228 1.1528 1.2006 1.184
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
MyLocs450 = 2275x1
97 464 830 1185 1540 1895 2263 2557 3005 3384
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
figure
plot(t450, sig450)
hold on
plot(t450(myLocs450),sig450(myLocs450), 'sr')
plot(t450(MyLocs450),sig450(MyLocs450), 'sg')
hold off
xlim([0 25])
It is simply not possible to resample the location indices as well as the signal, and have the location indices ‘make sense’ in any real way. As I mentioned earlier, find the peaks and locations of the resampled signal after resampl;ing it. Interpolating the data from the original signal to the resampled signal will simply not work. Just use findpeaks on the resampled signal and be done with it.
Notice the difference between the peak locations of the actual resampled signal and the resampled locations of the original signal. That approach just doesn’t work.
.

Connectez-vous pour commenter.

Tags

Question posée :

le 23 Juin 2024

Modifié(e) :

le 24 Juin 2024

Community Treasure Hunt

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

Start Hunting!

Translated by