⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_dec.c

📁 C实现了R波检测
💻 C
字号:
*****************************************************************************/  
#include "bdac.h"   
#include <STDIO.H>   
#include <STDLIB.H>   
  
#define ISO_LENGTH1  BEAT_MS50   
#define ISO_LENGTH2 BEAT_MS80   
#define ISO_LIMIT   20   
  
// Local prototypes.   
  
int IsoCheck(int *data, int isoLength);  
  
/**************************************************************** 
    等电位线的确定 
*****************************************************************/  
  
int IsoCheck(int *data, int isoLength)  
    {  
    int i, max, min ;  
  
    for(i = 1, max=min = data[0]; i < isoLength; ++i)  
        {  
        if(data[i] > max)  
            max = data[i] ;  
        else if(data[i] < min)  
            min = data[i] ;  
        }  
  
    if(max - min < ISO_LIMIT)  
        return(1) ;  
   return(0) ;  
    }  
  
/********************************************************************** 
 QRS 波的起点和终点,极性,等电位水平 
************************************************************************/  
  
#define INF_CHK_N   BEAT_MS40   
  
void AnalyzeBeat(int *beat, int *onset, int *offset, int *isoLevel,  
    int *beatBegin, int *beatEnd, int *amp)  
    {  
    int maxSlope = 0, maxSlopeI, minSlope = 0, minSlopeI  ;  
    int maxV, minV ;  
    int isoStart, isoEnd ;  
    int slope, i ;  
  
    // Search back from the fiducial mark to find the isoelectric   
    // region preceeding the QRS complex.   
  
    for(i = FIDMARK-ISO_LENGTH2; (i > 0) && (IsoCheck(&beat[i],ISO_LENGTH2) == 0); --i) ;  
  
    // If the first search didn't turn up any isoelectric region, look for   
    // a shorter isoelectric region.   
  
    if(i == 0)  
        {  
        for(i = FIDMARK-ISO_LENGTH1; (i > 0) && (IsoCheck(&beat[i],ISO_LENGTH1) == 0); --i) ;  
        isoStart = i + (ISO_LENGTH1 - 1) ;  
        }  
    else isoStart = i + (ISO_LENGTH2 - 1) ;  
  
    // Search forward from the R-wave to find an isoelectric region following   
    // the QRS complex.   
  
    for(i = FIDMARK; (i < BEATLGTH) && (IsoCheck(&beat[i],ISO_LENGTH1) == 0); ++i) ;  
    isoEnd = i ;  
  
    // Find the maximum and minimum slopes on the   
    // QRS complex.   
  
    i = FIDMARK-BEAT_MS150 ;  
    maxSlope = maxSlope = beat[i] - beat[i-1] ;  
    maxSlopeI = minSlopeI = i ;  
  
    for(; i < FIDMARK+BEAT_MS150; ++i)  
        {  
        slope = beat[i] - beat[i-1] ;  
        if(slope > maxSlope)  
            {  
            maxSlope = slope ;  
            maxSlopeI = i ;  
            }  
        else if(slope < minSlope)  
            {  
            minSlope = slope ;  
            minSlopeI = i ;  
            }  
        }  
  
    // Use the smallest of max or min slope for search parameters.   
  
    if(maxSlope > -minSlope)  
        maxSlope = -minSlope ;  
    else minSlope = -maxSlope ;  
  
    if(maxSlopeI < minSlopeI)  
        {  
  
        // Search back from the maximum slope point for the QRS onset.   
  
        for(i = maxSlopeI;  
            (i > 0) && ((beat[i]-beat[i-1]) > (maxSlope >> 2)); --i) ;  
            *onset = i-1 ;  
  
        // Check to see if this was just a brief inflection.   
  
        for(; (i > *onset-INF_CHK_N) && ((beat[i]-beat[i-1]) <= (maxSlope >>2)); --i) ;  
        if(i > *onset-INF_CHK_N)  
            {  
            for(;(i > 0) && ((beat[i]-beat[i-1]) > (maxSlope >> 2)); --i) ;  
            *onset = i-1 ;  
            }  
        i = *onset+1 ;  
  
        // Check to see if a large negative slope follows an inflection.   
        // If so, extend the onset a little more.   
  
        for(;(i > *onset-INF_CHK_N) && ((beat[i-1]-beat[i]) < (maxSlope>>2)); --i);  
        if(i > *onset-INF_CHK_N)  
            {  
            for(; (i > 0) && ((beat[i-1]-beat[i]) > (maxSlope>>2)); --i) ;  
            *onset = i-1 ;  
            }  
  
        // Search forward from minimum slope point for QRS offset.   
  
        for(i = minSlopeI;  
            (i < BEATLGTH) && ((beat[i] - beat[i-1]) < (minSlope >>2)); ++i);  
            *offset = i ;  
  
        // Make sure this wasn't just an inflection.   
  
        for(; (i < *offset+INF_CHK_N) && ((beat[i]-beat[i-1]) >= (minSlope>>2)); ++i) ;  
        if(i < *offset+INF_CHK_N)  
            {  
            for(;(i < BEATLGTH) && ((beat[i]-beat[i-1]) < (minSlope >>2)); ++i) ;  
            *offset = i ;  
            }  
        i = *offset ;  
  
        // Check to see if there is a significant upslope following   
        // the end of the down slope.   
  
        for(;(i < *offset+BEAT_MS40) && ((beat[i-1]-beat[i]) > (minSlope>>2)); ++i);  
        if(i < *offset+BEAT_MS40)  
            {  
            for(; (i < BEATLGTH) && ((beat[i-1]-beat[i]) < (minSlope>>2)); ++i) ;  
            *offset = i ;  
  
            // One more search motivated by PVC shape in 123.   
  
            for(; (i < *offset+BEAT_MS60) && (beat[i]-beat[i-1] > (minSlope>>2)); ++i) ;  
            if(i < *offset + BEAT_MS60)  
                {  
                for(;(i < BEATLGTH) && (beat[i]-beat[i-1] < (minSlope>>2)); ++i) ;  
                *offset = i ;  
                }  
            }  
        }  
  
    else  
        {  
  
        // Search back from the minimum slope point for the QRS onset.   
  
        for(i = minSlopeI;  
            (i > 0) && ((beat[i]-beat[i-1]) < (minSlope >> 2)); --i) ;  
            *onset = i-1 ;  
  
        // Check to see if this was just a brief inflection.   
  
        for(; (i > *onset-INF_CHK_N) && ((beat[i]-beat[i-1]) >= (minSlope>>2)); --i) ;  
        if(i > *onset-INF_CHK_N)  
            {  
            for(; (i > 0) && ((beat[i]-beat[i-1]) < (minSlope>>2));--i) ;  
            *onset = i-1 ;  
            }  
        i = *onset+1 ;  
  
        // Check for significant positive slope after a turning point.   
  
        for(;(i > *onset-INF_CHK_N) && ((beat[i-1]-beat[i]) > (minSlope>>2)); --i);  
        if(i > *onset-INF_CHK_N)  
            {  
            for(; (i > 0) && ((beat[i-1]-beat[i]) < (minSlope>>2)); --i) ;  
            *onset = i-1 ;  
            }  
  
        // Search forward from maximum slope point for QRS offset.   
  
        for(i = maxSlopeI;  
            (i < BEATLGTH) && ((beat[i] - beat[i-1]) > (maxSlope >>2)); ++i) ;  
        *offset = i ;  
  
        // Check to see if this was just a brief inflection.   
  
        for(; (i < *offset+INF_CHK_N) && ((beat[i] - beat[i-1]) <= (maxSlope >> 2)); ++i) ;  
        if(i < *offset+INF_CHK_N)  
            {  
            for(;(i < BEATLGTH) && ((beat[i] - beat[i-1]) > (maxSlope >>2)); ++i) ;  
            *offset = i ;  
            }  
        i = *offset ;  
  
        // Check to see if there is a significant downslope following   
        // the end of the up slope.   
  
        for(;(i < *offset+BEAT_MS40) && ((beat[i-1]-beat[i]) < (maxSlope>>2)); ++i);  
        if(i < *offset+BEAT_MS40)  
            {  
            for(; (i < BEATLGTH) && ((beat[i-1]-beat[i]) > (maxSlope>>2)); ++i) ;  
            *offset = i ;  
            }  
        }  
  
    // If the estimate of the beginning of the isoelectric level was   
    // at the beginning of the beat, use the slope based QRS onset point   
    // as the iso electric point.   
  
    if((isoStart == ISO_LENGTH1-1)&& (*onset > isoStart)) // ** 4/19 **   
        isoStart = *onset ;  
  
    // Otherwise, if the isoelectric start and the slope based points   
    // are close, use the isoelectric start point.   
  
    else if(*onset-isoStart < BEAT_MS50)  
        *onset = isoStart ;  
  
    // If the isoelectric end and the slope based QRS offset are close   
    // use the isoelectic based point.   
  
    if(isoEnd - *offset < BEAT_MS50)  
        *offset = isoEnd ;  
  
    *isoLevel = beat[isoStart] ;  
  
  
    // Find the maximum and minimum values in the QRS.   
  
    for(i = *onset, maxV = minV = beat[*onset]; i < *offset; ++i)  
        if(beat[i] > maxV)  
            maxV = beat[i] ;  
        else if(beat[i] < minV)  
            minV = beat[i] ;  
  
    // If the offset is significantly below the onset and the offset is   
    // on a negative slope, add the next up slope to the width.   
  
    if((beat[*onset]-beat[*offset] > ((maxV-minV)>>2)+((maxV-minV)>>3)))  
        {  
  
        // Find the maximum slope between the finish and the end of the buffer.   
  
        for(i = maxSlopeI = *offset, maxSlope = beat[*offset] - beat[*offset-1];  
            (i < *offset+BEAT_MS100) && (i < BEATLGTH); ++i)  
            {  
            slope = beat[i]-beat[i-1] ;  
            if(slope > maxSlope)  
                {  
                maxSlope = slope ;  
                maxSlopeI = i ;  
                }  
            }  
  
        // Find the new offset.   
  
        if(maxSlope > 0)  
            {  
            for(i = maxSlopeI;  
                (i < BEATLGTH) && (beat[i]-beat[i-1] > (maxSlope>>1)); ++i) ;  
            *offset = i ;  
            }  
        }  
  
      
    for(i = FIDMARK-BEAT_MS250;  
        (i >= BEAT_MS80) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 0); --i) ;  
    *beatBegin = i ;  
  
      
    if(*beatBegin == FIDMARK-BEAT_MS250)  
        {  
        for(; (i < *onset-BEAT_MS50) &&  
            (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 1); ++i) ;  
        *beatBegin = i-1 ;  
        }  
  
    // Rev 1.1   
    else if(*beatBegin == BEAT_MS80 - 1)  
        {  
        for(; (i < *onset) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 0); ++i);  
        if(i < *onset)  
            {  
            for(; (i < *onset) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 1); ++i) ;  
            if(i < *onset)  
                *beatBegin = i-1 ;  
            }  
        }  
  
      
  
    for(i = FIDMARK+BEAT_MS300;  
        (i < BEATLGTH) && (IsoCheck(&beat[i],BEAT_MS80) == 0); ++i) ;  
    *beatEnd = i ;  
  
    // If the signal was isoelectric at 300 ms. search backwards.   
/*  if(*beatEnd == FIDMARK+30) 
        { 
        for(; (i > *offset) && (IsoCheck(&beat[i],8) != 0); --i) ; 
        *beatEnd = i ; 
        } 
*/  
    // Calculate beat amplitude.   
  
    maxV=minV=beat[*onset] ;  
    for(i = *onset; i < *offset; ++i)  
        if(beat[i] > maxV)  
            maxV = beat[i] ;  
        else if(beat[i] < minV)  
            minV = beat[i] ;  
    *amp = maxV-minV ;  
  
    }  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -