当前位置:   article > 正文

几种常见的滤波算法_csdn滤波方式

csdn滤波方式

一、限幅滤波法

实现步骤:

根据经验法选择最大偏差值E。
|value_now - value_before| <= E,value_now有效,否则其无效且将其舍弃,最后令value_now = value_before。

实现程序:
#define E 10    //value取值范围为90~110
int value_init = 100;
int filter(int value_now)
{
       if ((value_now - value_before > E) || (value_before - value_now) > E)
       {
              return value_before;
       }
       return value_now;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

滤波优缺点:
优:可克服偶然误差。
缺:无法抑制周期性干扰;平滑度差。

二、中位值滤波法

实现步骤:

连续采样N次(N为奇数)
将其排序(任选一种排序算法
只取中间值

实现程序:
#define N 5     //根据传感器性能和主控芯片性能进行设置
int filter(void)
{
       int *buf = (int*)malloc(N * sizeof(int));
       char count, i, j, temp;
       for (count = 0; count < N; count++)
       {
              buf[count] = get_val(); //获取新的采样值
              delay();    //采样间隔
       }
       for (j = 0; j<N - 1; j++)        //采用冒泡排序
       {
              for (i = 0; i<N - j - 1; i++)
              {
                     if (buf[i]>buf[i + 1])
                     {
                           temp = buf[i];
                           buf[i] = buf[i + 1];
                           buf[i + 1] = temp;
                     }
              }
       }
       freebuf);       //释放内存块
       return buf[(N - 1) / 2];         //返回中间值
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

滤波优缺点:
优:可克服偶然误差;对缓慢变化的数据有很好的滤波效果。
缺:不适用于快速变化的数据。

三、算术平均滤波法

实现步骤:

取N个数据求均值
N大 --> 平滑度高,灵敏度低
N小 --> 平滑度低,灵敏度高
通常,流量N=12,压力N=4,液面,N=412,温度N=14

实现程序:
#define N 10
int filter(void)
{
       int sum = 0, count;
       for (count = 0; count < N; count++)
       {
              sum += get_val();    //获取采样值并求和
              delay();
       }
       return (sum / N);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

滤波优缺点:
优:适用于对一般具有随机干扰的信号进行滤波,信号会在此平均值附近上下波动。
缺:不适用于测量速度慢或要求数据计算快的实时控制;浪费运行内存。

四、中位值平均滤波法(二三结合)

实现步骤:

采样N个数据并排序
去掉数组头和尾(去除最大最小值)
计算(N-2)个数的平均数

实现程序:
#define N 12
int get_val();		//传感器采集数据函数
int filter()
{
       char count, i, j;
       int buf[N];
       int sum = 0, temp;
       for (count = 0; count < N; count++)
       {
              buf[count] = get_val();//获取采样值
              delay();
       }
       for (i = 0; i < N - 1; i++)      //冒泡排序
       { 
              for (j = 0; j < N - j - 1; j++)
              {
                     if (buf[i] > buf[i + 1])
                     {
                           temp = buf[i];
                           buf[i] = buf[i+1];
                           buf[i + 1] = temp;
                     }
              }
       }
       for (count = 1; count < N - 1; count++)
       {
                //由于数列已经排序了,所以去掉头尾就是去掉最小值和最大值
              sum += buf[count];   
       }
       return (sum / (N - 2));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

滤波优缺点:
优:对于偶然出现的脉冲性干扰;可消除由其引起的采样值偏差;对周期干扰有良好的抑制作用;平滑度高;适于高频振荡的系统。
缺:浪费运行内存。

五、限幅平均滤波法(一三结合)

实现步骤:

对数据进行限幅并对有效数据求平均值。

实现程序:
#define E 10         //误差允许值
#define N 12        //采样数据数目
char value_init = 100;  //采样参考值
char temp;
char getval();          //传感器读取数据函数
char filter(void)
{
	char i, value_now, value_before, sum, count = 0;
	//count:防止传感器出错而陷入死循环
	char *buf = (char*)malloc(N * sizeof(char));
	while (1)//直到取得有效值为止
	{
		temp = getval();
		if ((temp - value_init >E) || (temp - value_init <E))
		{
			 temp = getval();
			 count++;
			 if (count == 5)
           {
				 buf[0] = value_init;
				 break;
			  }
	    }
		else
		{
			buf[0] = temp;            //获取采样值用作上一次的值
			break;
		}
	}
	for (i = 1; i < N; i++)     //过滤超出范围的值
	{
		value_now = getval();     //获取采样值用作上一次的值
		if ((value_now - buf[i - 1]) > E || (buf[i - 1] - value_now) > E)
		{
			buf[i] = buf[i - 1];        //本次数据等于上一数据
		}
		else
			buf[i] = value_now;           //本次数据有效
	}
	for (i = 0; i < N; i++)
	{
		buf[i] = buf[i + 1];
		sum += buf[i];
	}
	return (sum / N);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

滤波优缺点:
优:限幅+滤波的优点。
缺:浪费运行内存。

六、递推平均滤波法

实现步骤:

将N个数据看做(FIFO)队列,每次采样到的数据替换掉最先进入队列的数据,最后求平均值。

实现程序:
#define N 12
int buf[N];         //全局变量,存储N个数据
static char i = 0;
int get_val();
int filter(void)
{
       char count;
       int sum = 0;
       if (i == N) i = 0; 
       //当数据大于数组长度,替换数据组的最先进入的一个数据相当于环形队列更新(FIFO)
       buf[i++] = get_val();
       for (count = 0; count < N; count++)
              sum += buf[count];
       return(sum / N);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
//注意 len �?��位!不是长度

\#define SLIDE_ISR(sum, data, p, len) \

  do                \
  {                 \
     sum = data;          \
     i  = (1 << len) - 1;     \
     for (; i > 0; i--)      \
    {               \
      p[i] = p[i - 1];     \
      sum += p[i];       \
    }               \
    p[0] = data;         \
    data = sum >> len;      \
    /* code */          \
  } while (0);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

滤波优缺点:
优:对周期性干扰有良好的抑制作用,平滑度高;适用于高频振荡的系统。
缺:灵敏度低;对偶然出现的脉冲性干扰的抑制作用较差;不易消除由于脉冲干扰所引起的采样值偏差; 不适用于脉冲干扰比较严重的场合;浪费运行内存。

七、加权递推平均滤波法(六-改进版)

实现步骤:

越接近现在时刻的数据,权取得越大。(给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。)

实现程序:
#define N 12
const char coe[] = { 1,2,3,4,5,6,7,8,9,10,11,12 };      //权值对照表
const char sum_coe = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12;//权和
//也可用递归方式生成这两个数组
char filter()
{
       char i;
       char value_buf[N];
       int sum = 0;
       for (i = 0; i < N; i++)
       {
              value_buf[i] = get_val();//获取采样数据
              delay();
       }
       for (i = 0; i < N; i++)
              sum += value_buf[i] * coe[i];
       return sum / sum_coe;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

滤波优缺点:
优:适用于有较大纯滞后时间常数的控制对象;采样周期较短的系统。
缺:对于纯滞后时间常数较小,采样周期较长;变化缓慢的信号不能迅速反应系统当前所受干扰的严重程度,滤波效果差。

八、递推有效值滤波

适用于PWM输入捕获J

bool slide_valid_filter(int new_data, int *buff, int buff_len, int valid_num, int allow_error)
{
  int count = 0;
  int i   = buff_len - 1;
  for (; i > 0; i--)  // 向右平移
  {
    buff[i] = buff[i - 1];
   if (abs(buff[i] - new_data) <= allow_error)  // 对比差值
    {
      count++;
    }
  }
  buff[0] = new_data;  // 压入新的
  return count >= valid_num;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

九、消抖滤波法

实现步骤:

设置一个滤波计数器。
将每次采样值与当前有效值比较:如果采样值==当前有效值,则返回上一个有效值;
如果采样值!=当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出);
如果计数器溢出,则将本次值替换当前有效值,并清计数器。

实现程序:
#define N 12
char get_val();
char filter()
{
       char count = 0;
       char value_now;
       char value_before = get_val();       //获取上一个采样数据
       while (value_now != value_before)
       {
              value_before = value_now;
                     count++;
              if (count >= N)
                     return value_now;
              delay();//适当延时
              value_now = get_val();//获取下一个采样数据
       }
       return value_before;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

滤波优缺点:
优:对于变化缓慢的被测参数有较好的滤波效果, 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。
缺:对于快速变化的参数不宜; 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。

十、一阶滞后滤波法

实现步骤:

一阶低通滤波法采用本次采样值与上次滤波输出值进行加权,得到有效滤波值,使得输出对输入有反馈作用。

实现程序:
#define thresholdValue 10           //阀门值
#define N 10                            //数据量
float dataArr[N] = { 99,102,108,89,98,86,89,90,93,105 };        //假设获得的数据
char flag0 = 0, flag1 = 0;                  //前一次比较与当前比较的方向位
float abs(float first, float second)        //求两个数的绝对值
{
       float abs_val;
       if(first>second)
       {
              abs_val = first - second;
              flag1 = 0;
       }
       else
       {
              abs_val = second - first;
              flag1 = 1;
       }
       return abs_val;
}

void filter(void)
{
       char i = 0, filterCount = 0, coeff = 0;  //filterCount:滤波计数器   coeff:滤波系数
       float Abs = 0.00;
       for (i = 1; i < N; i++)
       {
              Abs = abs(dataArr[i - 1], dataArr[i]);
              if (!flag1^flag0)     //异或
              {
                     filterCount++;
                     if (Abs >= thresholdValue)
                     {
                           filterCount += 2;
                     }
                     if (filterCount >= 12)
                           filterCount = 12;
                     coeff = 20 * filterCount;   //确定一阶滤波系数
              }
              else//消抖
                     coeff = 5;
              //一阶滤波算法
              if (flag1 == 0)//当前值小于前一个值
                     dataArr[i] = dataArr[i - 1] - coeff*(dataArr[i - 1] - 
dataArr[i]) / 256;
              else
                     dataArr[i] = dataArr[i - 1] + coeff*(dataArr[i - 1] - 
dataArr[i]) / 256;
              filterCount = 0;
              flag0 = flag1;
       }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

滤波优缺点:
优: 对周期性干扰具有良好的抑制作用;适用于波动频率较高的场合。

缺:相位滞后;灵敏度低;滞后程度取决于a值大小;不能消除滤波频率高于采样频率的1/2的干扰信号。

十一、卡尔曼滤波

实现步骤:

通过实时改变协方差来对系统进行修正。

实现程序:
/*------------------------------------------------------------------------------
|  Kalman Filter equations                                           
|                                                                        
|  state equation状态方程                                              
|  x(k) = A·x(k-1) + B·u(k) + w(k-1)                                
|  如果没有控制量则B·u(k)=0(如单纯测量温度湿度之类的)    
|                                                                                   
|  observations equation观测方程(传感器测得数据)         
|  z(k) = H·x(k) + y(k)                          
|                                                 
|  prediction equations预测方程                                 
|  x(k|k-1) = A·x(k-1|k-1) + B·u(k)               
|  P(k|k-1) = A·P(k-1|k-1)·A^T + Q                
|                                                 
|  correction equations修正方程                                 
|  K(k) = P(k|k-1)·H^T·(H·P(k|k-1)·H^T + R)^(-1)  
|  x(k|k) = x(k|k-1) + K(k)·(z(k) - H·x(k|k-1))   
|  P(k|k) = (I - K(k)·H)·P(k|k-1)     
------------------------------------------------------------------------------*/

/*
x和P只需要赋初值,每次迭代会产生新值;K用不着赋初值;
Q和R赋值以后在之后的迭代中也可以改。
x和P的初值是可以随便设的,强大的卡尔曼滤波器马上就能抹除不合理之处。
但需注意,P的初值不能为0,否则滤波器会认为已经没有误差了
R越大曲线越平滑,但会使滤波器变得不敏感,存在滞后
(Q和R取值也可以是时变的,可以识别跳变,可以自适应)
Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏
R:测量噪声,R增大,动态响应变慢,收敛稳定性变好
*/

#define KalmanQ 0.000001
#define KalmanR 0.0004

static double KalmanFilter(const double ResourceData, double ProcessNoiseQ, double MeasureNoiseR)
{
       double R = MeasureNoiseR;
       double Q = ProcessNoiseQ;
       static double x_last=-60;
       double x_mid = x_last;
       double x_now;
       static double p_last=1;
       double p_mid;
       double p_now;
       double K;
       x_mid = x_last;                        //x_last=x(k-1|k-1),x_mid=x(k|k-1)
       p_mid = p_last;                        //p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=过程噪声
       K = p_mid / (p_mid + R);
       x_now = x_mid + K*(ResourceData - x_mid);
       p_now = (1 - K)*p_mid + Q;
       p_last = p_now;
       x_last = x_now;
       return x_now;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

滤波优缺点:
优:能处理传感器噪声和过程噪声等。
缺:当运动目标长时间被遮挡时会存在目标跟踪丢失的情况 。

十二、其他滤波

(一)、IIR数字滤波器(Infinite Impulse Response Filter)
递归滤波器,也就是IIR数字滤波器,顾名思义,具有反馈。

(二)、FIR数字滤波器(Finite Impulse Response Filter)
有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。它具有线性相位、容易设计的优点,但相对于IIR滤波器它需要更多的参数,因此DSP需要更多的计算时间,对DSP的实时性有影响。

从性能上来说,IIR滤波器传递函数包括零点和极点两组可调因素,对极点的惟一限制是在单位圆内。因此可用较低的阶数获得高的选择性,所用的存储单元少,计算量小,效率高。但是这个高效率是以相位的非线性为代价的。选择性越好,则相位非线性越严重。FIR滤波器传递函数的极点固定在原点,是不能动的,它只能靠改变零点位置来改变它的性能。所以要达到高的选择性,必须用较高的阶数;对于同样的滤波器设计指标,FIR滤波器所要求的阶数可能比IIR滤波器高5-10倍,结果,成本较高,信号延时也较大;如果按线性相位要求来说,则IIR滤波器就必须加全通网络进行相位校正,同样要大大增加滤波器的阶数和复杂性。而FIR滤波器却可以得到严格的线性相位。

从结构上看,IIR滤波器必须采用递归结构来配置极点,并保证极点位置在单位圆内。由于有限字长效应,运算过程中将对系数进行舍入处理,引起极点的偏移。这种情况有时会造成稳定性问题,甚至产生寄生振荡。相反,FIR滤波器只要采用非递归结构,不论在理论上还是在实际的有限精度运算中都不存在稳定性问题,因此造成的频率特性误差也较小。此外FIR滤波器可以采用快速傅里叶变换算法,在相同阶数的条件下,运算速度可以快得多。

另外,也应看到,IIR滤波器虽然设计简单,但主要是用于设计具有分段常数特性的滤波器,如低通、高通、带通及带阻等,往往脱离不了模拟滤波器的格局。而FIR滤波器则要灵活得多,尤其是他易于适应某些特殊应用,如构成数字微分器或希尔波特变换器等,因而有更大的适应性和广阔的应用领域。

从上面的简单比较可以看到IIR与FIR滤波器各有所长,所以在实际应用时应该从多方面考虑来加以选择。从使用要求上来看,在对相位要求不敏感的场合,如语言通信等,选用IIR较为合适,这样可以充分发挥其经济高效的特点;对于图像信号处理,数据传输等以波形携带信息的系统,则对线性相位要求较高。如果有条件,采用FIR滤波器较好。当然,在实际应用中可能还要考虑更多方面的因素。

2,不论IIR和FIR,阶数越高,信号延迟越大;同时在IIR滤波器中,阶数越高,系数的精度要求越高,否则很容易造成有限字长的误差使极点移到单位园外。因此在阶数选择上是综合考虑的。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/236646
推荐阅读
相关标签
  

闽ICP备14008679号