OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9919|回复: 18

转自“程序匠人”的10种简单软件滤波,与大家分享

[复制链接]

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2013-7-23 17:10:08 | 显示全部楼层 |阅读模式
本帖最后由 745021926 于 2016-5-31 16:05 编辑

《匠人手记》里的10种软件滤波,感觉不错,在此作为自己的一个笔记,也跟大家分享。感谢“程序匠人”的奉献。
一、限幅滤波法
1、
先根据经验判断,确定两次采样允许的最大偏差值,设为A。
每次检测到新采样值时进行判断:
(1)如果本次新采样值与上一次滤波效果之差<=A,则本次采样值有效,令本次滤波结果=新采样值;
    (2)如果本次采样值与上次滤波结果之差>A,则本次采样值无效,放弃本次采样值,本次滤波结果=上次滤波结果。
2、例程
#define A 10
uchar Value;    //上次采样有效值
uchar AmplitudeLimiterFilter()
{
  uchar NewValue,ReturnValue;
  NewValue=GetAD();          //本次采样值
  if(((NewValue-Value)>A)||((Value-NewValue)>A))
  {
    ReturnValue=Value;
  }
  else
  {
    ReturnValue=NewValue;
  }
  return(ReturnValue);
}

二、中位值滤波法
1、连续采样N次值,把采样值按大小排列,取中间值为本次有效值。
2、例程
#define N 9
unchar MiddleValueFilter()
{
  unchar i,j,k;
  uchar temp;
  uchar ArrDataBuffer[N];
  for(i=0; i<N; i++) //一次采集N个数据放入数组中
  {
    ArrDataBuffer=GetAD();
    Delay();
  }
  for(j=0; j><N-1; j++) //采样值由小到大排列
  {
    for(k=0; k><N-j-1; k++)
    {
      if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
      {
        temp=ArrDataBuffer[k];
        ArrDataBuffer[k]=ArrDataBuffer[k+1];
        ArrDataBuffer[k+1]=temp;
      }
    }
  }
  return(ArrDataBuffer[(N-1)/2]);//取中间值
}

三、算术平均滤波法
1、连续取N个值进行算术平均运算。
N较大时,信号平滑度较高,但灵敏度较低;N较小,信号平滑度低,但灵敏度较高。
2、例程
#define N 12
uchar ArithmeticalAverageValueFilter()
{
  uchar i;
  uchar Value;
  uchar sum;
  sum=0;
  for(i=0; i<N; i++)
  {
    sum+=GetAD();
    Delay();
  }
  Value=sum/N;
  return(Value);
}
四、递推平均滤波法
1、把连续N个采集值看成一个队列,每次采集到的新数据放入队尾,并扔掉原来队首的数据。把队列中的N个数据进行平均计算,即可获得新的滤波结果。
2、例程
#define N 12
uchar Data[];
uchar Gilde(Data[])
{
  ucahr i,Value,sum;
  sum=0;
  Data[N]=GetAD();
  for(i=0; i><N; i++)
  {
    Data=Data[i+1];//所有数据左移,低位仍掉
    sum+=Data;
  }
  Value=sum/N;
  return(Value);
}

五、中位值平均滤波法
1、中位值平均滤波法又称脉冲干扰平均滤波法,相当于“中位值滤波法”+“算术平均滤波法”。
连续采集N个数据,去掉一个最大和最小值,然后计算N-2个数的平均值。
2、例程
#define N 12
uchar Middle()
{
  ucahr i,j,k,l;
  uchar temp;
  uchar ArrDataBuffer[N];
  uchar sum,Value;
  for(i=0; i><N; i++) //一次采集N个数据,存入数组
  {
    ArrDataBuffer=GetAD();
    Delay();
  }
  for(j=0; j><N-1; j++) //采样值由小到大排列
  {
    for(k=0; k><N-j-1; k++)
    {
      if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
      {
        temp=ArrDataBuffer[k];
        ArrDataBuffer[k]=ArrDataBuffer[k+1];
        ArrDataBuffer[k+1]=temp;
      }
    }
  }
  for(l=1; l<N-1; l++)
  {
    sum=ArrDataBuffer[l];
  }
  Value=Sum/(N-2);
  return(Value);
}

六、递推中位值平均滤波法
1、相当于“中位值滤波法”+“递推平均滤波法”。这种方法把连续N个值看成一个队列,每次采集到一个新数据放入队尾,并扔掉原来队首的值。 把队列中的N个数据先去掉一个最大值和最小值,然后计算N-2个数据的平均值。
2、例程
char Filter()
{
  char max.min;
  int sum;
  char i;
  QUEUE[0]=NewData;
  max=QUEUE[0];
  min=QUEUE[0];
  sum=QUEUE[0];
  for(i=n-1; i!=0; i--)
  {
    if(QUEUE>max)
    {
      max=QUEUE;
    }
    else if(QUEUE<min)
    {
      min=QUEUE;
    }
    sum+=QUEUE;
    QUEUE=QUEUE[i-1];
  }
  i=n-2;
  sum=sum-max-min+i/2;//加入(n-2)/2目的为了四舍五入
  sum=sum/i;
  return(sum);
}

七、限幅平均滤波法
1、相当于“限幅滤波法”+“递推平均滤波法”。每次采样先进行限幅处理,再进行队列平均滤波处理。
2、例程
#define A 10
#define N 12
uchar Data[N];
uchar Limit()
{
  ucahr i,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=Data[i+1];
    sum+=Data;
  }
  Value=sum/N;
  return(Value);
}

八、一阶滞后滤波法
1、本次结果滤波结果=a*本次采样值+(1-a)*上次结果。
                    a代表滤波系数,a=0--1。
2、例程

#define a 128
uchar Value;
ucahr OneFactorialFiler()
{
  uchar NewValue;
  uchar ReturnValue;
  NewValue=GetAD();
  ReturnValue=(255-a)*NewValue+a*Value;
  ReturnValue/=255;
  return(ReturnValue);
}

九、加权递推平均滤波法
1、加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权。通常是越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号的平滑度越低。
2、例程
#define N 10
#define CoeSum 55
const Coefficient[N]= {1,2,3,4,5,6,7,8,9,10};
uchar Data[N];
uchar AAGAFilter()
{
  uchar i,Value,sum;
  sum=0;
  Data[N]=GetAD();
  for(i=0; i><N; i++)
  {
    Data=Data[i+1];
    sum+=Data*Coefficient;
  }
  Value=sum/CoeSum;
  return(Value);
}

十、消抖滤波法
1、将每次采样值与当前有效值比较,如果采样值=当前有效值,则计数器清零,否则计数器加1。然后,判断计数器是否>=上限N(溢出)。如果溢出,将本次值替换当前有效值,并清计数器。
    2、例程
#define N 20
uchar count;
uchar Value;
uchar Avoid()
{
  uchar NewValue;
  if(NewValue==Value)
  {
    count=0;
  }
  else
  {
    count++;
    if(count>N)
    {
      count=0;
      Value=NewValue;
    }
  }
  return(Value);
}
博观而约取,厚积而薄发。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-23 19:12:19 | 显示全部楼层
回复 支持 反对

使用道具 举报

7

主题

165

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
213
金钱
213
注册时间
2013-6-18
在线时间
0 小时
发表于 2013-7-23 19:36:50 | 显示全部楼层
好东西,顶一个!!
只求每天都能把小事做好。
回复 支持 反对

使用道具 举报

8

主题

125

帖子

0

精华

高级会员

Rank: 4

积分
844
金钱
844
注册时间
2013-4-27
在线时间
120 小时
发表于 2013-7-23 19:48:56 | 显示全部楼层
给力啊
回复 支持 反对

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2012-8-31
在线时间
0 小时
发表于 2013-7-23 21:42:33 | 显示全部楼层
程序匠人的书我是买了二年了    不过这个滤波法还是前一阵才细细读过.不过没楼主那么好的心,还做好笔记了,我是先看 要用了再去找书的人 ...支持楼主,好东西
回复 支持 反对

使用道具 举报

11

主题

81

帖子

0

精华

高级会员

Rank: 4

积分
652
金钱
652
注册时间
2012-8-1
在线时间
68 小时
发表于 2013-7-24 08:49:34 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-7-24 09:39:29 | 显示全部楼层
赞一个啊。
楼主也玩430啊
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
 楼主| 发表于 2013-7-24 13:17:04 | 显示全部楼层
回复【5楼】hahalz:
---------------------------------
嗯,这些东西虽然不难,但是确实能够优化程序~
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
 楼主| 发表于 2013-7-24 13:18:20 | 显示全部楼层
回复【7楼】wwjdwy:
---------------------------------
嗯啊,但是只用过149~
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

4

主题

116

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
361
金钱
361
注册时间
2013-7-24
在线时间
13 小时
发表于 2013-7-24 14:14:33 | 显示全部楼层
LZ好人  好人一生平安
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-7-24 16:14:47 | 显示全部楼层
回复【9楼】745021926:
---------------------------------
我是用的2553,
对了一个定时器,可以同时用输入捕获,同时计时么
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
 楼主| 发表于 2013-7-24 20:35:11 | 显示全部楼层
回复【11楼】wwjdwy:
---------------------------------
可以的吧,捕获就是在中断服务程序中的
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-7-25 11:43:22 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
 楼主| 发表于 2013-7-30 11:41:54 | 显示全部楼层
回复【13楼】xouou_53320:
---------------------------------
感谢纠正!
博观而约取,厚积而薄发。
回复 支持 反对

使用道具 举报

53

主题

175

帖子

1

精华

高级会员

Rank: 4

积分
516
金钱
516
注册时间
2014-5-16
在线时间
7 小时
发表于 2014-11-20 09:29:01 | 显示全部楼层
谢谢分享,LZ有卡尔曼滤波的资料吗
本人新人,各位多包涵!
回复 支持 反对

使用道具 举报

24

主题

147

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2014-5-19
在线时间
28 小时
发表于 2014-11-20 10:01:31 | 显示全部楼层
不错不错,收藏了
回复 支持 反对

使用道具 举报

30

主题

705

帖子

1

精华

新手上路

积分
21
金钱
21
注册时间
2013-3-14
在线时间
52 小时
发表于 2014-11-20 10:17:22 | 显示全部楼层
非常不错,谢楼主。
原子哥是不是又要出黑科技了呀。^_^...
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2014-7-18
在线时间
2 小时
发表于 2015-7-20 20:50:04 | 显示全部楼层
回复【13楼】xouou_53320:
---------------------------------
五、中位值平均滤波法,中的最后参数L,应该是从1开始。
回复 支持 反对

使用道具 举报

2

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2014-7-24
在线时间
1 小时
发表于 2015-7-21 10:20:56 | 显示全部楼层
mark,好东西
电子制作很欢乐~!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 23:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表