Noninvasive Fetal ECG: The PhysioNet/Computing in Cardiology Challenge 2013 1.0.0
(5,309 bytes)
function [qrs threshold auxvec ]=detectqrsmultichannel2(ecg,samplingfreq)
L=size(ecg,2);
numchannels=size(ecg,1);
#extra filtering->inovation for detectqrsmultichannel_2
newmovageragefiltsize=40;#ms
movaveragekernel=ones(1,newmovageragefiltsize)/newmovageragefiltsize;
for i=1:numchannels
newecg(i,:)=filtfilt(movaveragekernel,1,ecg(i,:));
endfor
diffsignal=[zeros(numchannels,1),diff(newecg,1,2)];
auxvec=zeros(1,L);
windowtime=40;#ms related to qrs duration
windowL=floor(windowtime*samplingfreq/1000);
halfwindow=floor(windowL/2);
peak=[ones(1,halfwindow+1),-ones(1,halfwindow)];
for i=halfwindow+1:L-halfwindow
for c=1:numchannels
auxvec(i)+=abs(diffsignal(c,i-halfwindow:i+halfwindow)*peak');
endfor
endfor
basicvec=auxvec;
#replace peaks by area on a window time
# auxvec=zeros(1,L);
# newl=10;
# for i=newl+1:L-newl
# auxvec(i)=sum(basicvec(i-newl:i+newl));
# endfor
##################################################
## FIRST APPROACH ################################
###################################################
############### parameters that must be better tuned
threshold=50000;
maximumqrsinterval=1400*samplingfreq/1000;
##reduction of threshold value is done in a local base and not globally as in
## the first version
smallwindow=floor(400*samplingfreq/1000);##minimum QRS interval
###############
qrs=[];
emptysegments=[1,length(auxvec)];
while(!isempty(emptysegments)&&(threshold>10))
for i=1:length(emptysegments)/2
qrs=searchlocalmax(threshold, auxvec, qrs,
emptysegments(2*i-1), emptysegments(2*i),
maximumqrsinterval, smallwindow);
# qrs=searchlocalmaxnew(threshold, auxvec, qrs,
# emptysegments(2*i-1), emptysegments(2*i),
# smallwindow);
endfor
if(!isempty(qrs))
aux=zeros(1,length(auxvec));
aux(qrs(:))=1;
emptysegments=findemptysegments(aux, maximumqrsinterval);
endif
threshold=3/4*threshold;
#debug
#printf("size(qrs)=%d\n",size(qrs,2));fflush(stdout);
endwhile
minimumnumberqrsaux=50;
if(length(qrs)>minimumnumberqrsaux)
#repeat process to
#locate possible missing qrs using new maximumqrsinterval
medianqrsperiod=median(diff(qrs));
smallwindow=floor(min(3/4*medianqrsperiod,smallwindow));#new
maximumqrsinterval=max(floor(5/4*medianqrsperiod),2*smallwindow+10);
refthreshold=threshold;
aux=zeros(1,length(auxvec));
aux(qrs(:))=1;
emptysegments=findemptysegments(aux, maximumqrsinterval);
while(!isempty(emptysegments)&&(threshold/refthreshold>0.1))
for i=1:length(emptysegments)/2
qrs=searchlocalmax(threshold, auxvec, qrs,
emptysegments(2*i-1), emptysegments(2*i),
maximumqrsinterval, smallwindow);
endfor
if(!isempty(qrs))
aux=zeros(1,length(auxvec));
aux(qrs(:))=1;
emptysegments=findemptysegments(aux, maximumqrsinterval);
endif
threshold=3/4*threshold;
#printf("size(qrs)=%d\n",size(qrs,2));fflush(stdout);
endwhile
endif
if(length(qrs)>1)
assert(min(diff(qrs))>=smallwindow);
endif
#debug
#printf("after first approach siz qrs is %d\n",size(qrs,2));fflush(stdout);
##################################################
## SECOND APPROACH redefining maximumqrsinterval and smallwindow
###################################################
# threshold=50000;
# ##redefining thresholds
# differences=diff(qrs);
# avgdiff=mean(differences);
# maximumqrsinterval=floor(avgdiff+120*samplingfreq/1000);
# smallwindow=floor(avgdiff-160*samplingfreq/1000);
# ###############################################
# #repeating the cycle
# qrs=[];
# emptysegments=[1,length(auxvec)];
# #printf("length emptysegments is %d and threshold is %d\n",length(emptysegments),threshold);fflush(stdout);
# while(!isempty(emptysegments)&&(threshold>10))
# for i=1:length(emptysegments)/2
# qrs=searchlocalmax(threshold, auxvec, qrs,
# emptysegments(2*i-1), emptysegments(2*i),
# maximumqrsinterval, smallwindow);
# endfor
# if(!isempty(qrs))
# aux=zeros(1,length(auxvec));
# aux(qrs(:))=1;
# emptysegments=findemptysegments(aux, maximumqrsinterval);
# endif
# threshold=3/4*threshold;
# #debug
# #printf("size(qrs)=%d\n",size(qrs,2));fflush(stdout);
# endwhile
#####################################################
if(length(qrs)>1)
assert(min(diff(qrs))>=smallwindow);
endif
qrs=replacebylocmax(qrs,halfwindow,sum(ecg.^2));
endfunction
function res=replacebylocmax(setofpoints,halfwindow,abssignal)
numpoints=length(setofpoints);
res=zeros(1,numpoints);
L=length(abssignal);
for i=1:numpoints
if(setofpoints(i)>halfwindow)
if(setofpoints(i)<=L-halfwindow)
[a order]=max(abssignal(setofpoints(i)-halfwindow:\
setofpoints(i)+halfwindow));
res(i)=setofpoints(i)+order-halfwindow;
else
[a order]=max(abssignal(setofpoints(i)-halfwindow:L));
res(i)=setofpoints(i)+order-halfwindow;
endif
else
[a order]=max(abssignal(1:setofpoints(i)+halfwindow));
res(i)=order;
endif
endfor
endfunction