一阶差分法求取波形起始点、顶点

时间:2022-12-28 08:32:00

之前有发过一篇关于波形起始点检测的心得体会,后来有同学私信我,找源码。由于前一段时间很少上csdn,没有看到,这里表示抱歉。今天特意整理了一下之前的代码,摘选出来一段可以直接使用的代码。

`
#include <stdio.h>
#include <math.h>
void main()
{int i,N,n=0;
float x[5000],val,in[5000],out[5000],fdiff[5000],avar;

FILE *fp;
//void cubicSmooth;

if((fp=fopen("E:\\1.csv","rt"))==NULL)
{
printf("cannot open file\n");
return;
}

while (1) 
{
if(fscanf(fp,"%f,", &val) == EOF) break;
x[n]=val;
n++;
}
fclose(fp);

val=0; 
avar=0;
printf("%f\n",x[0]);
printf("%f\n",x[2729]);
for(i=0;i<n;i++){in[i]=x[i];}

for(N=0;N<=n;N++){
    if ( N < 7 )
    {
        for ( i = 0; i <= N - 1; i++ )
        {
            out[i] = in[i];
        }
    }
    else
    {
        out[0] = ( 39.0 * in[0] + 8.0 * in[1] - 4.0 * in[2] - 4.0 * in[3] +
                  1.0 * in[4] + 4.0 * in[5] - 2.0 * in[6] ) / 42.0;
        out[1] = ( 8.0 * in[0] + 19.0 * in[1] + 16.0 * in[2] + 6.0 * in[3] -
                  4.0 * in[4] - 7.0* in[5] + 4.0 * in[6] ) / 42.0;
        out[2] = ( -4.0 * in[0] + 16.0 * in [1] + 19.0 * in[2] + 12.0 * in[3] +
                  2.0 * in[4] - 4.0 * in[5] + 1.0 * in[6] ) / 42.0;
        for ( i = 3; i <= N - 4; i++ )
        {
            out[i] = ( -2.0 * (in[i - 3] + in[i + 3]) +
                       3.0 * (in[i - 2] + in[i + 2]) +
                      6.0 * (in[i - 1] + in[i + 1]) + 7.0 * in[i] ) / 21.0;
        }
        out[N - 3] = ( -4.0 * in[N - 1] + 16.0 * in [N - 2] + 19.0 * in[N - 3] +
                      12.0 * in[N - 4] + 2.0 * in[N - 5] - 4.0 * in[N - 6] + 1.0 * in[N - 7] ) / 42.0;
        out[N - 2] = ( 8.0 * in[N - 1] + 19.0 * in[N - 2] + 16.0 * in[N - 3] +
                      6.0 * in[N - 4] - 4.0 * in[N - 5] - 7.0 * in[N - 6] + 4.0 * in[N - 7] ) / 42.0;
        out[N - 1] = ( 39.0 * in[N - 1] + 8.0 * in[N - 2] - 4.0 * in[N - 3] -
                      4.0 * in[N - 4] + 1.0 * in[N - 5] + 4.0 * in[N - 6] - 2.0 * in[N - 7] ) / 42.0;
    }

}   

printf("尾点=%f\n",out[N-2]);

  fp=fopen("e:\\7点平滑.xls","w");
    for(i=0;i<n;i++)
        fprintf(fp,"%f\n",out[i]);
    fclose(fp);


    for(i=0;i<n;i++){
        avar+=out[i];}

    for(i=0;i<n-1;i++){
      fdiff[i]=out[i+1]-out[i];
      if(fdiff[i]<-50)printf("%f\n",fdiff[i]);
        if(fdiff[i]>50)printf("%f\n",fdiff[i]);
     }
    for(i=0;i<n-1;i++){
        val+=fdiff[i];}

      printf("%f\n",fdiff[0]);
      printf("差分和=%f\n",val);
      printf("幅值和=%f\n",avar);



 // FILE *fp;
    fp=fopen("e:\\一阶差分.xls","w");
    for(i=0;i<n-1;i++)
        fprintf(fp,"%f\n",fdiff[i]);
    fclose(fp);

     val=val/n-1;
     avar=avar/n;
   printf("差分均值val=%f\n",val);
   printf("幅值均值avr=%f\n",avar);

   val=fabs(val);
   printf("差分均值绝对值val=%f\n",val);


   for(i=0;i<n;i++)

   {
        if(fdiff[i-4]>0&&fdiff[i-3]>0&&fdiff[i-2]>0&&fdiff[i-1]>0&&fdiff[i]<=0&&fdiff[i+1]<0&&fdiff[i+2]<0)

      { 
          int j=0;
          int k=0;
          float ten_fdiffq=0;
          float ten_fdiffh=0;
          for(j=i-35;j<i-25;j++){ten_fdiffq+=fdiff[j];}
          for(j=i+15;j<i+25;j++){ten_fdiffh+=fdiff[j];}

          if(ten_fdiffq>1.25*val&&-ten_fdiffh>1.25*val)  //系数自选
          { 
              printf("位置%d\n峰值%f\n",i,out[i]);

              for(k=i-30;k>0;k--)
              {
                  if(fdiff[k]<=0)
                  {
                      printf("起始位置%d\n",k);
                      break;
                  }
              }
              for(k=i+30;k<n;k++)
              {
                  if(fdiff[k]>=0)
                  {
                      printf("终止位置%d\n",k);
                      break;
                  }
              }

          }
      }

    }
    getchar();`
 }
'

比较简单,希望对同学有所帮助。选择的系数是固定的,同学最好改成自适应的系数。中间使用的平滑算法,是借鉴自《几个简单的数据点平滑处理算法》。地址:http://blog.csdn.net/liyuanbhu/article/details/11119081#comments