• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

电赛常用滤波算法

参加电赛无论做什么都可能涉及到滤波,有硬件滤波和软件滤波。我给大家分享分享我知道的一些滤波算法。硬件滤波器最后再说,一入滤波深似海几本书都说不萌白。

先说简单的我也用过的几种:(预计一天或者两天更新一种算法)


第一种:限幅滤波算法 顾名思义就是根据经验或者一些给定作为一个对比标准与采样值进行对比,举个栗子,某系统的传感器的采样值根据经验知两次只差不能大于A则下一次的采样值和当前采样值的差的绝对值不能大于A则数据有效,若大于A则数据舍弃。

C程序如下:

#define A 15;

u8 amplitudeLimiterFilter(u8 oldValue)

{

    u8 newValue = getValue();获取当前传感器数据

    if( (newValue - oldValue) > A || (oldValue - newValue) >A))

    {

        return oldValue;

    }

    else

    {

        return newValue;

    }

}

oldValue可以用第一次采样值或者根据经验值设定

全部回复(9)
正序查看
倒序查看
2019-02-08 20:13

第二种:中位值滤波

连续采样A次(A取奇数)然后按值得大小排列 然后取中间值。

这种方法的好处就是能对缓慢变化的被测量(温度,液体高度等非突变量)进行良好的滤波但是对带有变化剧烈的突变量效果就不好了

#define A 10

int middleValueFilter()

{

    int value_buf[A];

    int i,j,k,temp;

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

    {

        value_buf[i] = getValue();

        Delay_ms();

    }

    for(j = 0 ; j < A-1; ++j)

    {

        for(k = 0; k

        {

            //从小到大排序,冒泡法排序

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

            {

                temp = value_buf[k];

                value_buf[k] = value_buf[k+1];

                value_buf[k+1] = temp;

            }

        }

0
回复
2019-02-09 19:21

3. 算数平均滤波

算数平均滤波是取N个数然后进行算数平均运算,这个N的大小就决定了信号的平滑度和信号灵敏性,这种方法对测量速度要求很快的系统不太适用而且需要消耗一定的RAM。下面看一下C程序。

#define  N  15

int Value;

int average()

{

unsigned int sum = 0;

int i;

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

{

sum+= getValue();

Delay_ms();

}

Value = sum/N;

Return(Value)

}

0
回复
2019-02-10 18:17

第四种:递推平均滤波(滑动平均滤波)

所谓的递推平均滤波就是取N组数据进行算数平均滤波然后数组左移一位扔掉第一个数把新采样到的数据放到数组的最后一位,依次进行。这种算法的好处就是滤波后的波形平滑度很高适用于高频震荡系统,缺点是灵敏度很低对脉冲干扰抑制性差,而且出现一次大幅度干扰后不易快速消除干扰,浪费ARM.(浪费ARM的问题可以进行改进一下改进的方法就是不去掉数组第一个数据而是去掉数组的平均值)

//C程序

#define N 20

int value_buf[N];

int moveAverageFilter(int curValue, int *sum, int *curNum)

{

      int i;

      if(*curNum < N)

      {

         value_buf[*curNum] = curValue;

         (*curNum)++;

         sum += curValue;

         retrun (*sum)/(*curNum);

       }

    else

    {

        //每次把后面的值往前移动一位

  //****************************************   

   sum -= value_buf[0];

         sum += curValue;

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

         {

             value_buf[i-1] = value_buf[i];

         }

         value_buf[N-1] = curValue;

         return (*sum)/N;

         // **************************************/

         //把新的值放在curNum%N的位置

         sum -= value_buf[*curNum%N];

         sum += curValue;

         value_buf[*curNum%N] = curValue;

         (*curNum)++;

          if(*curNum == 2N)

          {

            (*curNum) = N;

          }

     }

}    

//减去的值是上次的平均值

int moveAverageFilter(int *sum, int curValue, int num, int *curNum)

{

    if(num <= 0)

    {

        return 0;

    }

    else

    {

        if(*curNum < num)

        {

            ++(*curNum);

            *sum = *sum + curValue;

            return (*sum)/(*curNum);

        }

        else

        {

            *sum = *sum - (*sum)/num;

            *sum = (*sum + curValue);

            return *sum/num;

        }

    }

}

0
回复
2019-02-12 13:48
@喔喔呜呜
第四种:递推平均滤波(滑动平均滤波)所谓的递推平均滤波就是取N组数据进行算数平均滤波然后数组左移一位扔掉第一个数把新采样到的数据放到数组的最后一位,依次进行。这种算法的好处就是滤波后的波形平滑度很高适用于高频震荡系统,缺点是灵敏度很低对脉冲干扰抑制性差,而且出现一次大幅度干扰后不易快速消除干扰,浪费ARM.(浪费ARM的问题可以进行改进一下改进的方法就是不去掉数组第一个数据而是去掉数组的平均值)//C程序#defineN20intvalue_buf[N];intmoveAverageFilter(intcurValue,int*sum,int*curNum){     inti;     if(*curNum
坐等更新
0
回复
2019-02-12 19:19

第五种:中位值平均滤波算法(防脉冲干扰平均滤波法)

相当于“中位值滤波法”+“算术平均滤波法”    

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

融合了两种滤波的优点。对于偶然出现的脉冲性干扰,可消除有其引起的采样值偏差。对周期干扰有良好的抑制作用,平滑度高,适于高频振荡的系统。

C程序

#define N 10

int middleAverageFilter()

{

    int  i,j;

    int  temp,value,sum = 0;

    int  value_buf[N];

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

    {

        value_buf[i] = getValue();

        delay();

    }

      for(j = 0; j < N-1; ++j) //从小到大冒泡排序

    {

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

        {

            if(value_buf[i] > value_buf[i+1])

            {

                temp = value_buf[i];

                value_buf[i] = value_buf[i+1];

                value_buf[i+1] = temp;

            }

        }

    }

    for(i = 1; i < N-1; ++i)

    {

        sum += value_buf[i];

    }

    return sum/(N-2);

}

0
回复
2019-02-13 20:05

第六种:递推中位值滤波法

优点:对于偶然出现的脉冲性干扰,可消除由其引起的采样值偏差。对周期性干扰有良好的抑制作用,平滑度高;试用于高频振荡的系统。

缺点:测量速度慢

方法:取最近的N个值为一个队列,当前采样值放在队列最后,依次循环。计算时去掉最大值和最小值在取平均值

C程序:

char filter1(char NEW_DATA,char QUEUE[],char n)

{    char max;   

      char min;   

      int sum;  

      char i;   

      QUEUE[0]=NEW_DATA;     //新采样值入队列  

      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]

        sum=sum+QUEUE[i];                               //追加到和值     

        QUEUE[i]=QUEUE[i-1];                            //队列更新  

      }  

       i=n-2;   

       sum=sum-max-min+i/2;   

       sum=sum/i;                                      //平均值=(和值-最大值-最小值+n/2)/(队列长度-2)

                                                             //说明:+(n-2)/2的目的是为了四舍五入     

      return ((char)sum);

}       

0
回复
2019-02-20 16:56
收藏
0
回复
2019-05-24 12:20

单字节滑动中位值平均滤波功能:

1.将新的采样值压入队列       

 2.将队列数据减去最大值和最小值,然后其平均值(小数四舍五入)

*入口: NEW_DATA=新采样值        QUEUE=队列        n=队列长度*

出口:本次滤波结果(平均值)

优点:去掉最大值和最小值后计算N-2数据平均值 ,往后滑动,可消除偶然误差,比较实用。

缺点:速度慢消耗RAM。

**************************************************/

char filter1(char NEW_DATA,char QUEUE[],char n)

{   

 char max;   

 char min;   

 int sum;    

char i;    

QUEUE[0]=NEW_DATA;     //新采样值入队列   

 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]

  sum=sum+QUEUE[i];                                //追加到和值   

  QUEUE[i]=QUEUE[i-1];                            //队列更新  

  }  

 i=n-2;  

 sum=sum-max-min+i/2;   

 sum=sum/i;                                      //平均值=(和值-最大值-最小值+n/2)/(队列长度-2)

 return ((char)sum);                          //说明:+(n-2)/2的目的是为了四舍五入    

}       

0
回复
2019-05-30 09:15
@喔喔呜呜
单字节滑动中位值平均滤波功能:1.将新的采样值压入队列        2.将队列数据减去最大值和最小值,然后其平均值(小数四舍五入)*入口: NEW_DATA=新采样值        QUEUE=队列        n=队列长度*出口:本次滤波结果(平均值)优点:去掉最大值和最小值后计算N-2数据平均值 ,往后滑动,可消除偶然误差,比较实用。缺点:速度慢消耗RAM。**************************************************/char filter1(char NEW_DATA,char QUEUE[],char n){    char max;    char min;    int sum;    char i;    QUEUE[0]=NEW_DATA;     //新采样值入队列    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]
继续继续
0
回复