Noninvasive Fetal ECG: The PhysioNet/Computing in Cardiology Challenge 2013 1.0.0
(5,598 bytes)
function [fetal_QRSAnn_est,QT_Interval] = physionet2013(tm,ECG)
% Template algorithm for Physionet/CinC competition 2013. This function can
% be used for events 1 and 2. Participants are free to modify any
% components of the code. However the function prototype must stay the
% same:
%
% [fetal_QRSAnn_est,QT_Interval] = physionet2013(tm,ECG) where the inputs and outputs are specified
% below.
%
% inputs:
% ECG: 4x60000 (4 channels and 1min of signal at 1000Hz) matrix of
% abdominal ECG channels.
% tm : Nx1 vector of time in milliseconds
% output:
% FQRS: FQRS markers in seconds. Each marker indicates the position of one
% of the FQRS detected by the algorithm.
% QT_Interval: 1x1 estimated fetal QT duration (enter NaN or 0 if you do wish to calculate)
%
%
% Author: Joachim Behar - IPMG Oxford (joachim.behar@eng.ox.ac.uk)
% Last updated: March 3, 2013 Ikaro Silva
% ---- check size of ECG ----
if size(ECG,2)>size(ECG,1)
ECG = ECG';
end
fs = 1000; % sampling frequency
N = size(ECG,2); % number of abdominal channels
debug = 0; % enter debug mode?
ECG(find(isnan(ECG)==1)) = 0;
x=ECG(:,4);
x=x';
z=wavelet(x);
points=60000;
level=5; num_inter=6; wf='db5'; fs=1000;
clr={'k-','k-','k-','k-','b-'};
[Lo_D,Hi_D,Lo_R,Hi_R]=wfilters(wf);
[swa,swd] = swt(z,level,Lo_D,Hi_D);
if debug
figure(1);
subplot(level,1,1); plot(real(z)); grid on;axis tight;
for i=1:level
subplot(level+1,2,2*(i)+1);
plot(swa(i,:)); axis tight;grid on;xlabel('time');
ylabel(strcat('a ',num2str(i)));
subplot(level+1,2,2*(i)+2);
plot(swd(i,:)); axis tight;grid on;
ylabel(strcat('d ',num2str(i)));
end
end
ddw=zeros(size(swd));
pddw=ddw;
nddw=ddw;
posw=swd.*(swd>0);
pdw=((posw(:,1:points-1)-posw(:,2:points))<0);
pddw(:,2:points-1)=((pdw(:,1:points-2)-pdw(:,2:points-1))>0);
negw=swd.*(swd<0);
ndw=((negw(:,1:points-1)-negw(:,2:points))>0);
nddw(:,2:points-1)=((ndw(:,1:points-2)-ndw(:,2:points-1))>0);
ddw=pddw|nddw;
ddw(:,1)=1;
ddw(:,points)=1;
wpeak=ddw.*swd;
wpeak(:,1)=wpeak(:,1)+1e-10;
wpeak(:,points)=wpeak(:,points)+1e-10;
if debug
figure(2);
subplot(level+1,1,1); plot(real(z)); grid on;axis tight;
for i=1:level
subplot(level+1,1,i+1);
plot(wpeak(i,:)); axis tight;grid on;
ylabel(strcat('j= ',num2str(i)));
end
end
hlevel_wpeak=wpeak(level,:);
selevel_wpeak=wpeak(4,:);
sig=z;
peaks = PeakDetection(hlevel_wpeak,1/fs);
selevel_wpeak2=selevel_wpeak;
guilinglet=zeros(1,length(selevel_wpeak2));
for j=1:length(peaks)
guilinglet(peaks(j))=1;
end
D4_p=(guilinglet~=0);
D4_p2=(guilinglet~=0);
O_d4=60;%该参数确定在上一级搜索极大值的范围,可以调整。
O_d42=60;
for P_d4=O_d4:(length(guilinglet)-O_d4);
if D4_p(P_d4)==1;
for i=1:O_d4-1;
D4_p(P_d4-i)=1;
end ;
end;
end;
for P_d4=O_d42:(length(guilinglet)-O_d42);
if D4_p2(P_d4)==1;
for i=1:O_d42-1;
D4_p(P_d4+i)=1;
end ;
end;
end;
selevel_wpeak2=selevel_wpeak2.*D4_p;
selevel_wpeak3=selevel_wpeak-selevel_wpeak2;
fpeaks= PeakDetection(selevel_wpeak3,2/fs);
if debug
figure(10);
plot(selevel_wpeak3);
xlim([0,10000]);
% hold on,grid on;
% plot(QRSAnn1,sig(QRSAnn1)+(m-1)*2,'x','MarkerSize',7,...
% 'MarkerEdgeColor','g','LineWidth',2);
grid on;
xlim([0,10000]);
hold on,plot(fpeaks,sig(fpeaks)+(m-1)*2,'o','MarkerSize',7,...
'MarkerEdgeColor','r','LineWidth',2);grid on;
end
aa=1;
for i=1:length(fpeaks)
if fpeaks(i)>0
refpeaks(aa)=fpeaks(i);
aa=aa+1;
end
end
sortlength=20;
sign= abs(max(z))>abs(min(z));
for j=1:length(refpeaks)
maxorminpost=refpeaks(j);
if sign
for tt=1:sortlength
if refpeaks(j)-tt<=0
break;
else
if z(refpeaks(j)-tt)<z(maxorminpost)
maxorminpost=refpeaks(j)-tt;
end
end
end
for tt=1:sortlength
if refpeaks(j)+tt>=points
break;
else
if z(refpeaks(j)+tt)<z(maxorminpost)
maxorminpost=refpeaks(j)+tt;
end
end
end
else
for tt=1:sortlength
if refpeaks(j)-tt<=0
break;
else
if z(refpeaks(j)-tt)>z(maxorminpost)
maxorminpost=refpeaks(j)-tt;
end
end
end
for tt=1:sortlength
if refpeaks(j)+tt>=points
break;
else
if z(refpeaks(j)+tt)>z(maxorminpost)
maxorminpost=refpeaks(j)+tt;
end
end
end
end
refpeaks(j) =maxorminpost;
end
if debug
figure(13);
plot(sig + (m-1)*2,clr{m});
xlim([0,10000])
% hold on;grid on
% plot(QRSAnn,sig(QRSAnn)+(m-1)*2,'x','MarkerSize',7,...
% 'MarkerEdgeColor','g','LineWidth',2);
grid on;
xlim([0,10000]);
hold on,plot(refpeaks,sig(refpeaks)+(m-1)*2,'o','MarkerSize',7,...
'MarkerEdgeColor','r','LineWidth',2);grid on;
end
fetal_QRSAnn_est=refpeaks;
QT_Interval=0;
end