How to separate ECG signal into time sections?
2 ビュー (過去 30 日間)
古いコメントを表示
Hi,
I want to write a function that allows me to detect local maxima in a ECG signal. I want to separate the ECG signal into different time sections and then find the local maximum within each of those sections.
I am trying to do this but I am confused, how to approach this. I am new to MATLAB and not sure how to approach the coding
2 件のコメント
採用された回答
Meg Noah
2020 年 1 月 10 日
Wow - that is not the algorithm I would chose for this data at all! But here is a solution for implementing that algorithm
clc
close all
clear all
ECG = dlmread('ECG.csv');
nx = numel(ECG);
x = 1:nx;
figure('color','white','position',[70 100 600 900]);
subplot(3,1,1);
plot(x,ECG)
title({'Heartbeat data'})
xlabel('x')
ylabel('ECG(x)')
% visual inspection shows that a good width is 400 points
% need to zero pad this data to do the algorithm as directed
W = 400;
L = W/2;
xZeroPadded = 1:nx+W;
ECGZeroPadded = zeros(1,nx+W);
ECGZeroPadded(L+1:nx+L) = ECG;
subplot(3,1,2);
plot(xZeroPadded,ECGZeroPadded,'b')
title({'Zeropadded Heartbeat data'})
xlabel('x')
ylabel('ECG(x)');
% now look for the peaks in the data
nW = ceil((nx+W)./L) -2; % number of segments to search
xpeak = zeros(1,nW); % locations of the peaks
for isegment = 1:nW
xSegment0 = 1 + (isegment-1)*L;
xSegment1 = xSegment0 + W - 1;
ECGSegment = ECGZeroPadded(xSegment0:xSegment1);
xpeak(isegment) = xSegment0 + find(ECGSegment == max(ECGSegment),1,'first') - 1;
% fprintf(1,'%d %4.4d %4.4d %4.4d\n',isegment,xSegment0,xSegment1, ...
% xpeak(isegment));
end
% remove redundant data
xpeak = unique(xpeak);
hold on;
plot(xpeak,ECGZeroPadded(xpeak),'r+');
% subtract the zero-padding from the xpeak values
xpeak = xpeak - L;
subplot(3,1,3);
plot(x,ECG)
title({'Heartbeat data'})
xlabel('x')
ylabel('ECG(x)')
hold on;
plot(xpeak,ECG(xpeak),'r.','markersize',12);
fprintf(1,'index ECGValue\n');
for ipeak = 1:length(xpeak)
fprintf(1,'%4.4d %f\n',xpeak(ipeak),ECG(xpeak(ipeak)));
end
index ECGValue
0078 233.000000
0371 253.000000
0664 257.000000
0948 237.000000
1232 229.000000
1516 242.000000
1810 254.000000
2046 240.000000
2404 242.000000
2707 243.000000
2999 250.000000
2 件のコメント
Meg Noah
2020 年 1 月 10 日
編集済み: Meg Noah
2020 年 1 月 10 日
The algorithm description that Anon was supposed to code up sounded like it was found from visual inspection. I suppose you could threshold the ECG values to exclude a false detection. You could also have a pass that removes the smaller of two detections within a segment L. In other words, when you're first processing a segment, check if there is a detection wtihin 1:L and if so then compare it to the detection that you get. Like I said, this is not the algorithm I would use to find the peaks. Here's a way to find a lower bound for W from the data (seems to work):
ECG = dlmread('ECG.csv');
nx = numel(ECG);
idx = find(ECG > 200);
mask = ones(nx,1);
mask(idx) = 0;
labeled = bwlabel(mask);
stats = regionprops(labeled,ECG,'ALL');
centroids = [stats.Centroid]';
centroids = centroids(2:2:end);
W = ceil(max(diff(centroids)));
if (mod(W,2) ~= 0)
W = W + 1;
end
Meg Noah
2020 年 1 月 10 日
This also works - probably better:
ECG = dlmread('ECG.csv');
nx = numel(ECG); x = 1:nx;
idx = find(ECG > 200);
mask = zeros(nx,1);
mask(idx) = 1;
labeled = bwlabel(mask);
stats = regionprops(labeled,ECG,'ALL');
ipeak = zeros(length(stats),1);
for iblob = 1:length(stats)
ipeak(iblob) = stats(iblob).PixelIdxList(1) + ...
find( ECG(stats(iblob).PixelIdxList) == stats(iblob).MaxIntensity);
end
figure('color','white','position',[70 100 600 300]);
plot(x,ECG);
hold on
title({'Heartbeat data'})
xlabel('x')
ylabel('ECG(x)')
plot(x(ipeak),ECG(ipeak),'+');
W = ceil(max(diff(ipeak)));
if (mod(W,2) ~= 0)
W = W + 1;
end
その他の回答 (0 件)
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!