フィルタリングアルゴリズム大全


目次
1、リミットフィルタリング法(プログラム判定フィルタリング法とも呼ばれる)
2、中位値フィルタリング法
3、算術平均フィルタリング法
4、繰返し平均フィルタリング法(スライド平均フィルタリング法とも呼ばれる)
5、中位値平均フィルタリング法(パルス干渉防止平均フィルタリング法とも呼ばれる)
6、リミット平均フィルタリング法
7、一次ヒステリシスフィルタリング法
8、重み付け繰返し平均フィルタリング法
9、手ブレフィルタリング
10、リミットジッタフィルタリング法
11、カルマンフィルタはintタイプのデータをデフォルトでフィルタリングし、他のタイプをフィルタリングする必要がある場合は、プログラム内のすべてのintをlong、float、doubleに置き換えるだけでよい.
1、リミットフィルタリング法(プログラム判定フィルタリング法とも呼ばれる)
/*
A、  :     (         )
B、  :
          ,              (  A),
              :
               <=A,      ,
               >A,      ,     ,         。
C、  :
                     。
D、  :
                。
        。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;
int Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
  Value = 300;
}

void loop() {
  Filter_Value = Filter();       //         
  Value = Filter_Value;          //           ,        
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//      (         )
#define FILTER_A 1
int Filter() {
  int NewValue;
  NewValue = Get_AD();
  if(((NewValue - Value) > FILTER_A) || ((Value - NewValue) > FILTER_A))
    return Value;
  else
    return NewValue;
}

2、中位値フィルタリング法
/*
A、  :      
B、  :
        N (N   ), N         ,
              。
C、  :
                     ;
       、                    。
D、  :
       、            。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//       
#define FILTER_N 101
int Filter() {
  int filter_buf[FILTER_N];
  int i, j;
  int filter_temp;
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = Get_AD();
    delay(1);
  }
  //          (   )
  for(j = 0; j < FILTER_N - 1; j++) {
    for(i = 0; i < FILTER_N - 1 - j; i++) {
      if(filter_buf[i] > filter_buf[i + 1]) {
        filter_temp = filter_buf[i];
        filter_buf[i] = filter_buf[i + 1];
        filter_buf[i + 1] = filter_temp;
      }
    }
  }
  return filter_buf[(FILTER_N - 1) / 2];
}

3、算術平均フィルタリング法
/*
A、  :       
B、  :
       N            :
    N    :       ,      ;
    N    :       ,      ;
    N    :    ,N=12;  :N=4。
C、  :
                       ;
                  ,               。
D、  :
                               ;
        RAM。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//        
#define FILTER_N 12
int Filter() {
  int i;
  int filter_sum = 0;
  for(i = 0; i < FILTER_N; i++) {
    filter_sum += Get_AD();
    delay(1);
  }
  return (int)(filter_sum / FILTER_N);
}

4、繰返し平均フィルタリング法(スライド平均フィルタリング法とも呼ばれる)
/*
A、  :       (         )
B、  :
          N          ,        N,
                  ,            (      ),
         N           ,        。
    N    :  ,N=12;  ,N=4;  ,N=4-12;  ,N=1-4。
C、  :
                  ,    ;
              。
D、  :
        ,                  ;
                       ;
                   ;
        RAM。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//        (         )
#define FILTER_N 12
int filter_buf[FILTER_N + 1];
int Filter() {
  int i;
  int filter_sum = 0;
  filter_buf[FILTER_N] = Get_AD();
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = filter_buf[i + 1]; //       ,    
    filter_sum += filter_buf[i];
  }
  return (int)(filter_sum / FILTER_N);
}

5、中位値平均フィルタリング法(パルス干渉防止平均フィルタリング法とも呼ばれる)
/*
A、  :        (            )
B、  :
                       ,
       “      ”+“       ”。
        N   ,             ,
        N-2         。
    N    :3-14。
C、  :
       “      ”+“       ”        。
                ,              。
                 。
        ,         。
D、  :
          ,          。
        RAM。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//         (            )(  1)
#define FILTER_N 100
int Filter() {
  int i, j;
  int filter_temp, filter_sum = 0;
  int filter_buf[FILTER_N];
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = Get_AD();
    delay(1);
  }
  //          (   )
  for(j = 0; j < FILTER_N - 1; j++) {
    for(i = 0; i < FILTER_N - 1 - j; i++) {
      if(filter_buf[i] > filter_buf[i + 1]) {
        filter_temp = filter_buf[i];
        filter_buf[i] = filter_buf[i + 1];
        filter_buf[i + 1] = filter_temp;
      }
    }
  }
  //             
  for(i = 1; i < FILTER_N - 1; i++) filter_sum += filter_buf[i];
  return filter_sum / (FILTER_N - 2);
}


//          (            )(  2)
/*
#define FILTER_N 100
int Filter() {
  int i;
  int filter_sum = 0;
  int filter_max, filter_min;
  int filter_buf[FILTER_N];
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = Get_AD();
    delay(1);
  }
  filter_max = filter_buf[0];
  filter_min = filter_buf[0];
  filter_sum = filter_buf[0];
  for(i = FILTER_N - 1; i > 0; i--) {
    if(filter_buf[i] > filter_max)
      filter_max=filter_buf[i];
    else if(filter_buf[i] < filter_min)
      filter_min=filter_buf[i];
    filter_sum = filter_sum + filter_buf[i];
    filter_buf[i] = filter_buf[i - 1];
  }
  i = FILTER_N - 2;
  filter_sum = filter_sum - filter_max - filter_min + i / 2; // +i/2           
  filter_sum = filter_sum / i;
  return filter_sum;
}*/

6、リミット平均フィルタリング法
/*
A、  :       
B、  :
       “     ”+“       ”;
                    ,
                   。
C、  :
               ;
                ,                  。
D、  :
        RAM。
E、  :shenhaiyu 2013-11-01
*/

#define FILTER_N 12
int Filter_Value;
int filter_buf[FILTER_N];

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
  filter_buf[FILTER_N - 2] = 300;
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//        
#define FILTER_A 1
int Filter() {
  int i;
  int filter_sum = 0;
  filter_buf[FILTER_N - 1] = Get_AD();
  if(((filter_buf[FILTER_N - 1] - filter_buf[FILTER_N - 2]) > FILTER_A) || ((filter_buf[FILTER_N - 2] - filter_buf[FILTER_N - 1]) > FILTER_A))
    filter_buf[FILTER_N - 1] = filter_buf[FILTER_N - 2];
  for(i = 0; i < FILTER_N - 1; i++) {
    filter_buf[i] = filter_buf[i + 1];
    filter_sum += filter_buf[i];
  }
  return (int)filter_sum / (FILTER_N - 1);
}

7、一次ヒステリシスフィルタリング法
/*
A、  :       
B、  :
     a=0-1,      =(1-a)*     +a*      。
C、  :
                   ;
                。
D、  :
        ,    ;
           a   ;
                  1/2     。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;
int Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
  Value = 300;
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//        
#define FILTER_A 0.01
int Filter() {
  int NewValue;
  NewValue = Get_AD();
  Value = (int)((float)NewValue * FILTER_A + (1.0 - FILTER_A) * (float)Value);
  return Value;
}

8、重み付け繰返し平均フィルタリング法
/*
A、  :         
B、  :
                ,              ;
       ,         ,     。
                ,      ,        。
C、  :
                    ,          。
D、  :
               、      、       ;
                       ,     。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//          
#define FILTER_N 12
int coe[FILTER_N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};    //      
int sum_coe = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12; //      
int filter_buf[FILTER_N + 1];
int Filter() {
  int i;
  int filter_sum = 0;
  filter_buf[FILTER_N] = Get_AD();
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = filter_buf[i + 1]; //       ,    
    filter_sum += filter_buf[i] * coe[i];
  }
  filter_sum /= sum_coe;
  return filter_sum;
}

9、手ブレフィルタリング
/*
A、  :     
B、  :
             ,              :
         =     ,      ;
         <>     ,    +1,        >=  N(  );
           ,            ,     。
C、  :
                       ;
                    /            。
D、  :
               ;
                           ,               。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;
int Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
  Value = 300;
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//      
#define FILTER_N 12
int i = 0;
int Filter() {
  int new_value;
  new_value = Get_AD();
  if(Value != new_value) {
    i++;
    if(i > FILTER_N) {
      i = 0;
      Value = new_value;
    }
  }
  else
    i = 0;
  return Value;
}

10、リミットジッタフィルタリング法
/*
A、  :       
B、  :
       “     ”+“     ”;
       ,   。
C、  :
       “  ” “  ”   ;
       “     ”      ,          。
D、  :
               。
E、  :shenhaiyu 2013-11-01
*/

int Filter_Value;
int Value;

void setup() {
  Serial.begin(9600);       //        
  randomSeed(analogRead(0)); //       
  Value = 300;
}

void loop() {
  Filter_Value = Filter();       //         
  Serial.println(Filter_Value); //     
  delay(50);
}

//         300      
int Get_AD() {
  return random(295, 305);
}

//        
#define FILTER_A 1
#define FILTER_N 5
int i = 0;
int Filter() {
  int NewValue;
  int new_value;
  NewValue = Get_AD();
  if(((NewValue - Value) > FILTER_A) || ((Value - NewValue) > FILTER_A))
    new_value = Value;
  else
    new_value = NewValue;
  if(Value != new_value) {
    i++;
    if(i > FILTER_N) {
      i = 0;
      Value = new_value;
    }
  }
  else
    i = 0;
  return Value;
}

11、カルマンフィルタ
//******     ************
		
float code Q_angle=0.001;  
float code Q_gyro=0.003;
float code R_angle=0.5;
float code dt=0.01;	                  //dt kalman       ;
char  code C_0 = 1;
float xdata Q_bias, Angle_err;
float xdata PCt_0, PCt_1, E;
float xdata K_0, K_1, t_0, t_1;
float xdata Pdot[4] ={0,0,0,0};
float xdata PP[2][2] = { { 1, 0 },{ 0, 1 } };

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

//Kalman  ,20MHz      0.77ms;

void Kalman_Filter(float Accel,float Gyro)		
{
	Angle+=(Gyro - Q_bias) * dt; //    

	
	Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-            

	Pdot[1]=- PP[1][1];
	Pdot[2]=- PP[1][1];
	Pdot[3]=Q_gyro;
	
	PP[0][0] += Pdot[0] * dt;   // Pk-              
	PP[0][1] += Pdot[1] * dt;   // =         
	PP[1][0] += Pdot[2] * dt;
	PP[1][1] += Pdot[3] * dt;
		
	Angle_err = Accel - Angle;	//zk-    
	
	PCt_0 = C_0 * PP[0][0];
	PCt_1 = C_0 * PP[1][0];
	
	E = R_angle + C_0 * PCt_0;
	
	K_0 = PCt_0 / E;
	K_1 = PCt_1 / E;
	
	t_0 = PCt_0;
	t_1 = C_0 * PP[0][1];

	PP[0][0] -= K_0 * t_0;		 //         
	PP[0][1] -= K_0 * t_1;
	PP[1][0] -= K_1 * t_0;
	PP[1][1] -= K_1 * t_1;
		
	Angle	+= K_0 * Angle_err;	 //    
	Q_bias	+= K_1 * Angle_err;	 //    
	Gyro_y   = Gyro - Q_bias;	 //   (    )   =   

}



//*********************************************************
//     (     )
//*********************************************************

void Angle_Calcu(void)	 
{
	//------   --------------------------

	//   2g ,    :16384 LSB/g
	//     ,x=sinx    (  ), deg = rad*180/3.14
	//  x>=sinx,   1.3    

	Accel_x  = GetData(ACCEL_XOUT_H);	  //  X    
	Angle_ax = (Accel_x - 1100) /16384;   //      ,      (  )
	Angle_ax = Angle_ax*1.2*180/3.14;     //      ,


    //-------   -------------------------

	//   2000deg/s ,    :16.4 LSB/(deg/s)

	Gyro_y = GetData(GYRO_YOUT_H);	      //      Y    -30  
	Gyro_y = -(Gyro_y + 30)/16.4;         //      ,      ,        
	//Angle_gy = Angle_gy + Gyro_y*0.01;  //           .	

	
	//-------       -----------------------

	Kalman_Filter(Angle_ax,Gyro_y);       //         


	/*//-------    -----------------------

	//                        ,   
    //            ,                 
	//0.5     ,      ;0.01     10ms	
		
	Angle = Angle + (((Angle_ax-Angle)*0.5 + Gyro_y)*0.01);
															  
}  

この文書は次のとおりです.https://www.geek-workshop.com/thread-7694-1-1.html