1. 程式人生 > >十大濾波演算法程式大全(精心整理版)

十大濾波演算法程式大全(精心整理版)

1、限幅濾波法

*函式名稱:AmplitudeLimiterFilter()-限幅濾波法 *優點:能有效克服因偶然因素引起的脈衝干擾 *缺點:無法抑制那種週期性的干擾,且平滑度差 *說明:   1、呼叫函式      GetAD(),該函式用來取得當前值   2、變數說明      Value:最近一次有效取樣的值,該變數為全域性變數      NewValue:當前取樣的值      ReturnValue:返回值   3、常量說明      A:兩次取樣的最大誤差值,該值需要使用者根據實際情況設定 *入口:Value,上一次有效的取樣值,在主程式裡賦值

*出口:ReturnValue,返回值,本次濾波結果 ****************************************************/ #define  A   10 unsigned char Value unsigned char AmplitudeLimiterFilter() {    unsigned char NewValue;    unsigned char ReturnValue;    NewValue=GatAD();    if(((NewValue-Value)>A))||((Value-NewValue)>A)))    ReturnValue=Value;    else ReturnValue=NewValue;    return(ReturnValue); }

理解:使用前提是已知採回來的數值應該在什麼範圍或精確值

2、中位值濾波法

/*****************************************************函式名稱:MiddlevalueFilter()-中位值濾波法 *優點:能有效克服因偶然因素引起的波動干擾;對溫度、液        位等變化緩慢的被測引數有良好的濾波效果 *缺點:對流量,速度等快速變化的引數不宜 *說明:   1、呼叫函式      GetAD(),該函式用來取得當前值      Delay(),基本延時函式   2、變數說明      ArrDataBuffer[N]:用來存放一次性採集的N組資料      Temp:完成冒泡法試用的臨時暫存器      i,j,k:迴圈試用的引數值   3、常量說明      N:陣列長度 *入口: *出口:value_buf[(N-1)/2],返回值,本次濾波結果

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

#define N 11

unsigned char MiddlevalueFilter()

{   unsigned char value_buf[N];   unsigned char i,j,k,temp;   for(i=0;i<N;i++)   {     value_buf[i] = get_ad();     delay();   }   for (j=0;j<N-1;j++)   {    for (k=0;k<N-j;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;      }    }   }   return value_buf[(N-1)/2]; }

是不是需要的執行時間比較長  放在定時中斷或者DMA中斷都會影響12864的顯示速度

就像在DMA 中斷里加了一個printf語句

3、算術平均濾波法

/*********************************************************說明:連續取N個取樣值進行算術平均運算 優點:試用於對一般具有隨機干擾的訊號進行濾波。這種訊號的特點是       有一個平均值,訊號在某一數值範圍附近上下波動。 缺點:對於測量速度較慢或要求資料計算較快的實時控制不適用。 **********************************************************/

#define N 12

char filter() {   unsigned int sum = 0;   unsigned char i;

  for (i=0;i<N;i++)   {     sum + = get_ad();     delay();   }   return(char)(sum/N); }

最基本的一種濾波方式  應該也是最常用的  但其濾波效果很中

4、遞推平均濾波法(又稱滑動平均濾波法)

/***************************************************說明:把連續N個取樣值看成一個佇列,佇列長度固定為N。       每次取樣到一個新資料放入隊尾,並扔掉隊首的一       次資料。把佇列中的N各資料進行平均運算,既獲得       新的濾波結果。 優點:對週期性干擾有良好的抑制作用,平滑度高;適用於高頻振盪的系統 缺點:靈敏度低;對偶然出現的脈衝性干擾的抑制作用較差,不適於脈衝幹       擾較嚴重的場合 不適合用於開關電源電路 ****************************************************/

#define N 12

unsigned char value_buf[N];

unsigned char filter() {   unsigned char i;   unsigned char value;   int sum=0;

  value_buf[i++] = get_ad();       //採集到的資料放入最高位   for(i=0;i<N;i++)   {     value_buf[i]=value_buf[i+1];   //所有資料左移,低位扔掉     sum += value_buf[i];   }   value = sum/N;   return(value); }

5、中位值平均濾波法(又稱防脈衝干擾平均濾波法)

/******************************************** 說明:採一組佇列去掉最大值和最小值  優點:融合了兩種濾波的優點。對於偶然出現的脈衝性干擾,可消        除有其引起的取樣值偏差。對週期干擾有良好的抑制作用,        平滑度高,適於高頻振盪的系統。  缺點:測量速度慢 *********************************************/

#define N 12

uchar filter()

{   unsigned char i,j,k,l;   unsigned char temp,sum=0,value;   unsigned char value_buf[N],;

  for(i=0;i<N;i++)   {     value_buf[i] = get_ad();     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];

  value = sum/(N-2);   return(value); }

6、遞推中位值濾波法 /************************************************ 優點:對於偶然出現的脈衝性干擾,可消除由其引起的取樣值偏差。        對週期性干擾有良好的抑制作用,平滑度高;試用於高頻振盪        的系統  缺點:測量速度慢 *************************************************/

char filter(char new_data,char queue[],char n) {   char max,min;   char 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]<min)     min=queue[i];     sum=sum+queue[i];     queue[i]=queue[i-1];   }

  i=n-2;   sum=sum-max-min+i/2;     //說明:+i/2的目的是為了四捨五入   sum=sum/i;

  return(sum); }

7、限幅平均濾波法

/************************************************ 優點:對於偶然出現的脈衝性干擾,可消除有其引起的取樣值偏差。 *************************************************/ #define A 10 #define N 12

unsigned char data[]; unsigned char filter(data[]) {   unsigned char i;   unsigned char 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); }

8、一階滯後濾波法

/*****************************************************函式名稱:filter()-一階滯後濾波法 *說明:   1、呼叫函式      GetAD(),該函式用來取得當前值      Delay(),基本延時函式   2、變數說明      Or_data[N]:採集的資料      Dr0_flag、Dr1_flag:前一次比較與當前比較的方向位      coeff:濾波係數      F_count:濾波計數器   3、常量說明      N:陣列長度      Thre_value:比較門檻值 *入口: *出口: *****************************************************/

#define Thre_value  10 #define  N   50

float Or_data[N]; unsigned char Dr0_flag=0,Dr1_flag=0;

void abs(float first,float second) {  float abs;  if(first>second)  {    abs=first-second;    Dr1_flag=0;  }  else  {    abs=second-first;    Dr1_flag=1;  }  return(abs); } 

void filter(void) {   uchar i=0,F_count=0,coeff=0;   float Abs=0.00;

  //確定一階濾波係數   for(i=1;i<N;i++)     {       Abs=abs(Or_data[i-1],Or_data[i]);/*C語言中的逗號有2種意思: 1.表示"分隔號"的意思,就和語文中的逗號一個意思; 2.表示"逗號運算子"的意思,用它將2個表示式連線起來.例如:   3+5,6+8  就稱為逗號表示式,又稱為"順序求值運算子".逗號表示式的一般形式為   表示式1,表示式2   逗號表示式的求解過程是:先求解表示式1,再求解表示式2.整個逗號表示式的值是表示式2的值.例如,上面的表示式"3+5,6+8"的值是14.*/

      if(!(Dr1_flag^Dr0_flag))                    //前後資料變化方向一致  ^異或運算子       {          F_count++;         if(Abs>=Thre_value)         {           F_count++;           F_count++;         }         if(F_count>=12)         F_count=12;         coeff=20*F_count;         }       else                                        //去抖動       coeff=5;       //一階濾波演算法       if(Dr1_flag==0)                             //當前值小於前一個值       Or_data[i]=Or_data[i-1]-coeff*(Or_data[i-1]-Or_data[i])/256;       else       Or_data[i]=Or_data[i-1]+coeff*(Or_data[i]-Or_data[i-1])/256;                 F_count=0;                                  //濾波計數器清零       Dr0_flag=Dr1_flag;     } }

9、加權遞推平均濾波法

    A、方法:

        是對遞推平均濾波法的改進,即不同時刻的資料加以不同的權

        通常是,越接近現時刻的資料,權取得越大。

        給予新取樣值的權係數越大,則靈敏度越高,但訊號平滑度越低

    B、優點:

        適用於有較大純滯後時間常數的物件

        和取樣週期較短的系統

    C、缺點:

        對於純滯後時間常數較小,取樣週期較長,變化緩慢的訊號

        不能迅速反應系統當前所受干擾的嚴重程度,濾波效果差

/************************************************************  coe:陣列為加權係數表,存在程式儲存區。  sum_coe:加權係數和  ************************************************************/

#define N 12

const char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12}; const char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;

unsigned char filter() {   unsigned char i;   unsigned char value_buf[N];   int sum=0;

  for (i=0;i<N;i++)   {     value_buf[i] = get_ad();     delay();   }

  for (i=0,i<N;i++)   {     value_buf[i]=value_buf[i+1];     sum += value_buf[i]*coe[i];   }

  sum/=sum_coe;   value=sum/N;   return(value); }

10、消抖濾波法

    A、方法:

        設定一個濾波計數器

        將每次取樣值與當前有效值比較:

        如果取樣值=當前有效值,則計數器清零

        如果取樣值<>當前有效值,則計數器+1,並判斷計數器是否>=上限N(溢位)

            如果計數器溢位,則將本次值替換當前有效值,並清計數器

    B、優點:

        對於變化緩慢的被測引數有較好的濾波效果,

        可避免在臨界值附近控制器的反覆開/關跳動或顯示器上數值抖動

    C、缺點:

        對於快速變化的引數不宜

        如果在計數器溢位的那一次取樣到的值恰好是干擾值,則會將干擾值當作有效值匯入系統

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

*************************************************/ #define N 12

unsigned char filter() {   unsigned char i=0;   unsigned char new_value;   new_value = get_ad();   if(value !=new_value);   {     i++;     if (i>N)     {       i=0;       value=new_value;     }   }   else i=0;   return(value); }