常见滤波算法区别和应用
常用滤波算法简介
1、限幅滤波
基本方法:比较相邻n 和 n - 1时刻的两个采样值y(n)和 y(n – 1),根据经验确定两次采样允许的最大偏差。如果两次采样值的差值超过最大偏差范围 ,认为发生可随机干扰 ,并认为后一次采样值y(n)为非法值 ,应予删除 ,删除y(n)后 ,可用y(n – 1) 代替y(n);若未超过所允许的最大偏差范围 ,则认为本次采样值有效。
适用场景:随机干扰
C语言实现:
/*******************************************************
* 函 数 名: Limit_Filter
* 功能说明: 限幅滤波,消除随机干扰
* 形 参: NULL
* 返 回 值: 限幅滤波结果
*******************************************************/
#define A 10 /* 可根据实际情况调整 */
int Limit_Filter()
{
static int old_value; /* 上一次采样值 */
int new_value; /* 当前采样值 */
/* 获取新的采样值 */
new_value = get_ad();
/* 超出最大偏差范围,返回上一次采样值*/
if ( ( new_value - old_value > A ) || ( old_value - new_value > A ))
return old_value;
/* 未超出最大偏差范围,返回新采样值,并记录*/
old_value = new_value;
return new_value;
}
2、中值平均滤波
基本方法:对某一被测参数连续采样 n次,然后再把采样值按大小排列 ,取中间值为本次采样值。
适用场景:克服偶然因素引起的波动或采样不稳定引起的误码等脉冲干扰。对温度、液位等缓慢变化的被测参数用此法能收到良好的滤波效果,但是对于流量压力等快速变化的参数一般不宜采用中位值滤波法
C语言实现:
/*******************************************************
* 函 数 名: Median_Filter
* 功能说明: 中值平均滤波,克服采样不稳或波动问题
* 形 参: NULL
* 返 回 值: 中值滤波结果
*******************************************************/
#define SAMP_N 20 /* 采样总次数,可根据实际情况调整 */
#define TAKE_N 10 /* 取样次数,可根据实际情况调整 */
int Median_Filter()
{
int value_buf[SAMP_N];
int cnt,i,j,temp;
/* 取样SAMP_N次 */
for (cnt=0; cnt<SAMP_N; cnt++)
{
value_buf[cnt] = get_ad();
delay();
}
/* 使用选择法升序排序 */
for (i=0;i<SAMP_N-1;i++)
{
for (j=i+1;j<SAMP_N;j++)
{
if (value_buf[i] > value_buf[j])
{
temp = value_buf[j];
value_buf[j] = value_buf[i];
value_buf[i] = temp;
}
}
}
/* 取中间TAKE_N个数做均值处理 */
for (i=(SAMP_N-TAKE_N)/2; i<(SAMP_N/2+TAKE_N/2); i++)
{
temp += value_buf[i];
}
return temp / TAKE_N;
}
3、滑动平均滤波
基本方法:采用队列存储采样数据,设队列的长度为 N,每进行一次测量 ,把测量结果放于队尾,而扔掉原来队首的一个数据,这样在队列中始终就有 N 个“最新”的数据,然后取n次采样值的平均值。
适用场景:适用于对一般的具有随机干扰的信号进行滤波。这种信号的特点是信号本身在某一数值范围附近上下周期波动,如测量流量、液位
C语言实现:
/*******************************************************
* 函 数 名: Average_Filter
* 功能说明: 均值滤波,克服周期波动问题
* 形 参: NULL
* 返 回 值: 均值滤波结果
*******************************************************/
#define SAMP_N 20 /* 采样总次数,可根据实际情况调整 */
int Average_Filter()
{
static int value_buf[SAMP_N]={0}, buf_cnt=0, avg_cnt=0;
int cnt,temp;
if(buf_cnt <= SAMP_N)
{
if(buf_cnt == SAMP_N)buf_cnt = 0;
if(avg_cnt < SAMP_N)avg_cnt++;
}
value_buf[buf_cnt++] = get_ad(); /*将数据存入环形buf中*/
for(cnt=0; cnt<avg_cnt; i++)/*对环形buf中数据求和*/
{
temp += value_buf[i];
}
return temp / SAMP_N;
}
4、一阶滤波
基本方法:采用本次采样值与上次滤波输出值进行加权,得到有效滤波值,使得输出对输入有反馈作用。计算公式为:Y(n)=αX(n)(1-α)Y(n-1);
α=滤波系数,X(n)=本次采样值,Y(n-1)=上次滤波输出值,Y(n)=本次滤波输出值
适用场景:对周期性干扰具有一定的抑制作用,适用于波动频率较高的场合
C语言实现:
/*******************************************************
* 函 数 名: FirstOrder_Filter
* 功能说明: 一阶滤波,克服周期干扰
* 形 参: NULL
* 返 回 值: 均值滤波结果
*******************************************************/
#define F 0.5 /* 滤波系数,可根据实际情况调整 */
int FirstOrder_Filter()
{
static int old_value; /* 上一次采样值 */
int temp, new_value; /* 当前采样值 */
new_value = get_ad();
temp = F * new_value + (1-F)*old_value;
old_value = new_value;
return temp;
}
滤波算法对比
滤波算法 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
限值滤波 | 能有效克服因偶然因素引起的随机干扰 | 无法抑制那种周期性的干扰,平滑度差 | 随机干扰严重,单次采样 |
中值平均滤波 | 能有效克服因偶然因素引起的脉冲干扰和随机干扰 | 不宜使用于快速变化的参数 | 变化比较缓慢的被测量值,多次采样,采样频率高 |
滑动平均滤波 | 对周期性干扰有良好的抑制作用,平滑度高 | 灵敏度低,不易消除脉冲干扰引起的误差 | 适用于高频振荡的系统,多次采样,采样频率较低 |
一阶滤波 | 对周期性干扰有一定的抑制作用 | 相位滞后,灵敏度低,滞后程度取决于F的值 | 适用于高频振荡的系统,单次采样 |