C语言软件滤波

看到《匠人手记》里介绍的10种软件滤波,感觉不错,在此作为自己的一个笔记,也希望跟大家分享。在这感谢“程序匠人”的奉献。

一、限幅滤波法

1、先根据经验判断,确定两次采样允许的最大偏差值,设为A。

每次检测到新采样值时进行判断:

(1)如果本次新采样值与上一次滤波效果之差<=A,则本次采样值有效,令本次滤波结果=新采样值;

(2)如果本次采样值与上次滤波结果之差>A,则本次采样值无效,放弃本次采样值,本次滤波结果=上次滤波结果。

2、例程

#define A 10

uchar Value;    //上次采样有效值

uchar AmplitudeLimiterFilter()

{

    uchar NewValue,ReturnValue;

    NewValue=GetAD();          //本次采样值

    if(((NewValue-Value)>A)||((Value-NewValue)>A)))

    ReturnValue=Value;

    else ReturnValue=NewValue;

    return(ReturnValue);

}

 

二、中位值滤波法

1、连续采样N次值,把采样值按大小排列,取中间值为本次有效值。

2、例程

#define N 9

unchar MiddleValueFilter()

{

unchar i,j,k;

uchar temp;

uchar ArrDataBuffer[N];

for(i=0;i<N;i++)  //一次采集N个数据放入数组中

{

  ArrDataBuffer[i]=GetAD();

  Delay();

}

for(j=0;j<N-1;j++)//采样值由小到大排列

{

  for(k=0;k<N-j-1;k++)

  {

    if(ArrDataBuffer[k]>ArrDataBuffer[k+1])

    {

      temp=ArrDataBuffer[k];

      ArrDataBuffer[k]=ArrDataBuffer[k+1];

      ArrDataBuffer[k+1]=temp;

    }

  }

}

return(ArrDataBuffer[(N-1)/2]);//取中间值

}

 

三、算术平均滤波法

1、连续取N个值进行算术平均运算。

N较大时,信号平滑度较高,但灵敏度较低;N较小,信号平滑度低,但灵敏度较高。

2、例程

#define N 12

uchar ArithmeticalAverageValueFilter()

{

uchar i;

uchar Value;

uchar sum;

sum=0;

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

{

sum+=GetAD();

Delay();

}

Value=sum/N;

return(Value);

}

四、递推平均滤波法

1、把连续N个采集值看成一个队列,每次采集到的新数据放入队尾,并扔掉原来队首的数据。把队列中的N个数据进行平均计算,即可获得新的滤波结果。

2、例程

#define N 12

uchar Data[];

uchar Gilde(Data[])

{

 ucahr i,Value,sum;

sum=0;

Data[N]=GetAD();

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

{

  Data[i]=Data[i+1];//所有数据左移,低位仍掉

  sum+=Data[i];

}

Value=sum/N;

return(Value);

}

 

五、中位值平均滤波法

1、中位值平均滤波法又称脉冲干扰平均滤波法,相当于“中位值滤波法”+“算术平均滤波法”。

连续采集N个数据,去掉一个最大和最小值,然后计算N-2个数的平均值。

2、例程

#define N 12

uchar Middle()

{

ucahr i,j,k,l;

uchar temp;

uchar ArrDataBuffer[N];

uchar sum,Value;

for(i=0;i<N;i++)//一次采集N个数据,存入数组

{

   ArrDataBuffer[i]=GetAD();

   Delay();

}

for(j=0;j<N-1;j++)//采样值由小到大排列

{

  for(k=0;k<N-j-1;k++)

  {

    if(ArrDataBuffer[k]>ArrDataBuffer[k+1])

    {

      temp=ArrDataBuffer[k];

      ArrDataBuffer[k]=ArrDataBuffer[k+1];

      ArrDataBuffer[k+1]=temp;

    }

  }

}

for(l=0;l<N-1;l++)

{

  sum=ArrDataBuffer[l];

}

Value=Sum/(N-2);

return(Value);

}

 

六、递推中位值平均滤波法

1、相当于“中位值滤波法”+“递推平均滤波法”。这种方法把连续N个值看成一个队列,每次采集到一个新数据放入队尾,并扔掉原来队首的值。把队列中的N个数据先去掉一个最大值和最小值,然后计算N-2个数据的平均值。

2、例程

char Filter()

{

char max.min;

int sum;

char i;

QUEUE[0]=NewData;

max=QUEUE[0];

min=QUEUE[0];

sum=QUEUE[0];

for(i=n-1;i!=0;i--)

{

  if(QUEUE[i]>max) max=QUEUE[i];

  else if(QUEUE[i]<min) min=QUEUE[i];

  sum+=QUEUE[i];

  QUEUE[i]=QUEUE[i-1]; 

}

  i=n-2;

 sum=sum-max-min+i/2;//加入(n-2)/2目的为了四舍五入

 sum=sum/i;

 return(sum);

}

 

七、限幅平均滤波法

1、相当于“限幅滤波法”+“递推平均滤波法”。每次采样先进行限幅处理,再进行队列平均滤波处理。

2、例程

#define A 10

#define N 12

uchar Data[N];

uchar Limit()

{

  ucahr i,Value,sum;

  Data[N]=GetAD();

  if(((Data[N]-Data[N-1])>A)||((Data[N-1]-Data[N])>A)))

   Data[N]=Data[N-1]; 

   else Data[N]=NewValue;

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

{

  Data[i]=Data[i+1];

  sum+=Data[i];

}

Value=sum/N;

return(Value);

}

 

八、一阶滞后滤波法

1、本次结果滤波结果=a*本次采样值+(1-a)*上次结果。

a代表滤波系数,a=0--1。

2、例程

#define a 128

uchar Value;

ucahr OneFactorialFiler()

{

uchar NewValue;

uchar ReturnValue;

NewValue=GetAD();

ReturnValue=(255-a)*NewValue+a*Value;

ReturnValue/=255;

return(ReturnValue);

}

 

九、加权递推平均滤波法

1、加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权。通常是越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号的平滑度越低。

2、例程

#define N 10

#define CoeSum 55

const Coefficient[N]={1,2,3,4,5,6,7,8,9,10};

uchar Data[N];

uchar AAGAFilter()

{

 uchar i,Value,sum;

 sum=0;

 Data[N]=GetAD();

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

{

  Data[i]=Data[i+1];

  sum+=Data[i]*Coefficient[i];

}

Value=sum/CoeSum;

return(Value);

}

 

十、消抖滤波法

1、将每次采样值与当前有效值比较,如果采样值=当前有效值,则计数器清零,否则计数器加1。然后,判断计数器是否>=上限N(溢出)。如果溢出,将本次值替换当前有效值,并清计数器。

2、例程

#define N 20

uchar count;

uchar Value;

uchar Avoid()

{

uchar NewValue;

if(NewValue==Value) count=0;

else

{

  count++;

  if(count>N)

  {

     count=0;

     Value=NewValue;

  }

}

return(Value);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值