心电信号求qrs点坐标

it2022-12-28  71

算法思路:

这是2020年江苏省电赛A题的一部分设计要求,计算ADS1292模块传出的心电信号值,找到QRS坐标,ADS1292是一个24位高精度的ADC,通过两路的差分放大接收激励引脚产生的电压变化(心电信号的变化)。

ECG信号为准周期信号,R为一个波段的最大值,Q为R前的最小值,S为整个波段最小值(R后最小值),信号建议使用SG滤波,可以保留信号变化的一种类似于最小二乘法的滤波,然后对数组取差值,前后差值最大的点为R,R前差值为正,直到Q点,R后插值为负,直到S点。


代码:

提示:这是对一组250个采样点,分区间找最大值,判断组内有效心电信号波段个数,计算相应QRS坐标的简易算法,用的一组处理后的心电数据txt里的。

#include <stdio.h> #include <math.h> int main(void) {     int i,j,max_piont[6]={0},min1_piont[6]={0},min2_piont[6]={0},sz[461],max[6]={0},min1[6]={0},min2[6]={0};     int len = 85;//real = 85 , org = 461(460)     int base = 500;//651:b,1563:c   ,, real = 0     int a[85]={0};     int max_buf[5] = {0};     int max_buf_val[5] = {0};     int box[250] ={0};     int box_len = 250;     int window = 50;     int window_cnt =0;     int max_temp=0;     int temp;     int ture=0;     float xinglv=0,  time = 0.004 ,xinglv_jiange1=0,xinglv_jiange2=0;//time要按采样时间算 //从TXT中读250个数字     FILE *fpRead=fopen("box2.txt","r");//b,c ,,  real = real_1     if(fpRead==NULL)     {         return 0;     }     for(i=0;i<box_len;i++)     {         fscanf(fpRead,"%d ",&box[i]);         //printf("%d ",a[i]);     } //把250分成5个区间,取最大值     for(i=0;i<5;i++)     {         max_temp = 0;         for(j = i*window;j < i*window+window;j++)         {         max_temp=(max_temp>box[j])?max_temp:box[j];         if(max_temp==box[j])              {             max_buf[i]=j;             max_buf_val[i]=box[j];             }         }                  window_cnt = window_cnt + 1;     } //排序         for(i=0;i<5;i++)     {         for(j=i+1;j<5;j++)         {             if(max_buf_val[i]<max_buf_val[j])             {             temp=max_buf_val[i];             max_buf_val[i]=max_buf_val[j];             max_buf_val[j]=temp;             temp=0;             temp=max_buf[i];             max_buf[i]=max_buf[j];             max_buf[j]=temp;             }         }     }          for(i=0;i<5;i++)//计算有效的波峰     {         if(max_buf_val[i]>max_buf_val[0]-5) ture++;     } //取前有效个,算qs     for(i=0;i<ture;i++)         {                 for(j=max_buf[i];j<max_buf[i]+10;j++)             {                 min1[i]=(min1[i]<box[i])?min1[i]:box[j];                 if(min1[i]==box[j]) min1_piont[i]=j;//S             }             for(j=max_buf[i]-12;j<max_buf[i];j++)             {                 min2[i]=(min2[i]<box[j])?min2[i]:box[j];                 if(min2[i]==box[j]) min2_piont[i]=j;//R             }         }     //算心率,心律不齐         xinglv = 60/(((max_buf[1]-max_buf[0])+(max_buf[2]-max_buf[1]))/2*time);    //    (time)not have  value !!! just test         xinglv_jiange1 = max_buf[1]-max_buf[0];         xinglv_jiange2 = max_buf[2]-max_buf[1];     //输出         printf("  %d %d %d %d %d  , %d\n",max_buf[0],max_buf[1],max_buf[2],max_buf[3],max_buf[4],window_cnt);         printf("  %d %d %d %d %d  , %d\n",max_buf_val[0],max_buf_val[1],max_buf_val[2],max_buf_val[3],max_buf_val[4],window_cnt);         printf(" R-R间距 %f %f \n",xinglv_jiange1,xinglv_jiange2);         printf(" 心率 %f 间隔误差 %f \n",xinglv,(max_buf[1]-max_buf[0])/(max_buf[2]-max_buf[1]));         for(i=0;i<ture;i++)         {         printf("  输入%d个整数中Q%d是:%d \n其数组下标是:%d 是第:%d个\n",box_len,i,min2[i],min2_piont[i],min2_piont[i]+base);         printf("  输入%d个整数中R%d是:%d \n其数组下标是:%d 是第:%d个\n",box_len,i,max_buf_val[i],max_buf[i],max_buf[i]+base);         printf("  输入%d个整数中S%d是:%d \n其数组下标是:%d 是第:%d个\n",box_len,i,min1[i],min1_piont[i],min1_piont[i]+base);         }         ture = 0;     return 0; }

结果对于处理过的数据还是比较准的


误差分析:

提示:还是需要处理两最大值采样点x坐标过近的问题,滤除可能的误差。


 

最新回复(0)