信号采集是非常常见的需求,我们也总是希望采集到的数据是纯净而真实的,但这只是我们的希望。环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响,于是就有了滤波器的用武之地。这里我们讨论的主要是软件实现的数字滤波器,这一篇我们就来讨论基于递推算术平均算法的平滑滤波器。

1、问题的提出

在我们通过AD采集获取数据时,不可避免会受到干扰信号的影响,而且很多时候我们希望尽可能的将这种影响减到最小。为实现这一目的,人们想了很多办法,有硬件方面的,也有软件方面的。在硬件难以改变或者软件能够达到相应效果时,我们一般采用软件方法来实现,通常称之为数字滤波。

实现数字滤波的算法有很多种,根据不同的应用需求我们可以选择不同滤波算法来实现。对于一般的AD采集最常见的是周期性干扰和随机性噪声,对于此类干扰一般采用算术平均的方法就能得到比较理想的效果。其计算公式如下:

使用简单的算术平均值算法虽然能够实现滤波,但在一些情况下有一个问题可能会有影响,那就是当做算术平均的数量比较大时会出现曲线并不是十分平滑的情况。这很容易理解,因为一次采集n个数做算术平均得到一个结果,当n越大则间隔的时间就越长。为了解决这一问题我们并不是甲酸完后就将n个数同时丢弃,而是将最早的数丢弃并采用最新采集的数代替,这就是所谓的递推算术平均算法。但其计算公式并没有发生变化。

2、算法设计

我们如何实现这种递推方式的平滑滤波器呢?首先我们来看一看一般的算术平均算法是如何实现的。算术平均算法就是采集N个数然后对这N个数取平均值作为最终的结果。我们将这些数的序列记录如下:

这N个数计算完毕后就会丢弃,然后再采集N个数。很显然,如果N值较大,采集所耗费的时间跨度就会比较长,数据看起来可能就并不那么平滑,而且数据的输出速率会慢很多,也不能展示数据的变化过程。而递推平均算法则不存在这些问题。同样是一个长度为N的数据队列,但没采样一次数据,我们就用最新的数据替换掉最久的数据,并输出算术平均值。我们将这些数的序列记录如下:

这样每采样一个数据我们都会输出一个滤波后的数据,而不是等待采集N个数据后才会输出,这样既可保证数据的连续性也可达到平滑滤波的效果。

3、代码实现

我们分析了平滑滤波器的实现算法,接下来我们来讨论如何实现这一滤波器。首先我们将滤波器作为一个对象,我们实现的滤波器操作也将面向这一对象来实现。那么我们实现对滤波器对象的操作需要确定该对象的那些属性呢?

作为滤波器肯定需要获取当前采集到的数据值;同时我们为了实现对N个数据的递推平均就需要有一个存储这N个数的队列;我们需要记录最新的数据硬件存储到哪个位置就需要一个位置指针;同时我们也需要知道N的大小,所以我们将它们都定义滤波器对象的属性。平滑滤波的过程必须要计算算术平均值,而递推算术平均则是在每次采集一个数据之时都计算平均值,可是如果N值较大时,就会存在大量的重复计算。我们考虑到上一次采样的平均值已经得到,我们将其记录下来的话就可以用最新采集的数据替换掉最老的数据,从而得到新的平均值,所以我们将上一时间的输出值记录下来作为对象的一个属性。根据以上分析我们可定义滤波器对象类型为:

/*定义平滑滤波对象类型*/
typedef struct FilterObject{float newValue;       //最新测量值float lastValue;      //上一个输出值float *buffer;        //数据缓存区int16_t position;    //写操作位置指针uint16_t bufCount;    //滤波的数量
}FilterObjectType;

我们获得了滤波器对象,接下来我们基于该对象实现平滑滤波器。对于平滑滤波自然是要采取计算平均值的过程。但我们使用了循环队列的操作方式,所以判断新数据指针当前所处的位置。具体实现如下:

/*平滑滤波处理函数,返回滤波后的值 */
float SmoothingFilter(FilterObjectType *filter)
{float result=0.0;if(filter->position<0){for(int i=0;i<filter->bufCount;i++){filter->buffer[i]=filter->newValue;}filter->position=0;filter->lastValue=filter->newValue;}if(filter->position>=filter->bufCount){filter->position=0;}result=filter->lastValue-filter->buffer[filter->position]/filter->bufCount;result=result+filter->newValue/filter->bufCount;filter->buffer[filter->position++]=filter->newValue;filter->lastValue=result;filter->newValue=0.0;return result;
}

4、应用总结

我们实现了基于算术平均的平滑滤波器,对于消除周期性干扰有良好的抑制作用,对于一般具有随机干扰的信号也能进行滤波。对于数据平滑度较高有不错的效果。

但是这种滤波方式有几点是需要注意的。第一,它的灵敏度低。这很好理解,因为我们总是对N个数采取平均值算法,所以新数据对平均值的影响有限,数据变化不明显,响应较慢,而且N越大越明显。第二.对偶然出现的脉冲性干扰的抑制作用较差。第三,不易消除由于脉冲干扰所引起的采样值偏差。所以这种滤波器并不适用于脉冲干扰比较严重的场合。

欢迎关注:

滤波器开发之一:基于算数平均的平滑滤波器相关推荐

  1. 滤波器开发之二:基于算数平均的带阻平滑滤波器

    信号采集是非常常见的需求,我们也总是希望采集到的数据是纯净而真实的,但这只是我们的希望.环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响,于是就有了滤波 ...

  2. 滤波器开发之三:基于算数平均的阶进平滑滤波器

    信号采集是非常常见的需求,我们也总是希望采集到的数据是纯净而真实的,但这只是我们的希望.环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响,于是就有了滤波 ...

  3. 滤波器开发之五:基于算术平均的限幅滤波器

      通过AD采集数据时,我们总是希望采集到的数据是纯净而真实的,而实际上环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响.所以软件实现的数字滤波器应运而 ...

  4. 滤波器开发之四:基于算术平均的中值滤波器

      在信号采集系统中,除了我们感兴趣的数据外,难免会有一些来自于环境的干扰信号.但我们总希望我们得到的数据是纯净而真实的,为了达到这个目标,我们不得不想办法去除这些干扰信号,于是滤波器就成为我们必不可 ...

  5. 一. 卡尔曼滤波器开发实践之一: 五大公式详解

    既然标题名称是开发实践,本系列文章将主要介绍如何在工程实践中使用卡尔曼滤波器,至于卡尔曼滤波器的五大公式如何推导而来,网上有很多大拿们写的都很精彩,这里不再叙述.可以参考了下面两篇博文: 1. 卡尔曼 ...

  6. 六.卡尔曼滤波器开发实践之六: 无损卡尔曼滤波器(UKF)进阶-白话讲解篇

    本系列文章主要介绍如何在工程实践中使用卡尔曼滤波器,分七个小节介绍: 一.卡尔曼滤波器开发实践之一: 五大公式 二.卡尔曼滤波器开发实践之二:  一个简单的位置估计卡尔曼滤波器 三.卡尔曼滤波器(EK ...

  7. 七.卡尔曼滤波器开发实践之七: 无损卡尔曼滤波器(UKF)进阶-实例篇

    本系列文章主要介绍如何在工程实践中使用卡尔曼滤波器,分七个小节介绍: 一.卡尔曼滤波器开发实践之一: 五大公式 二.卡尔曼滤波器开发实践之二:  一个简单的位置估计卡尔曼滤波器 三.卡尔曼滤波器(EK ...

  8. java 写一个商店_Java Web开发之基于Session的购物商店实现方法

    本文实例讲述了Java Web开发之基于Session的购物商店实现方法.分享给大家供大家参考,具体如下: package cn.com.shopping; import java.io.IOExce ...

  9. 认识Web前端、Web后端、桌面app和移动app新开发模式 - 基于Node.js环境和VS Code工具...

    认识Web.桌面和移动app新开发模式 - 基于Node.js环境和VS Code工具 一.开发环境的搭建(基于win10) 1.安装node.js和npm 到node.js官网下载安装包(包含npm ...

最新文章

  1. 第十、十一周项目-阅读程序,写出这些程序的运行结果(3)
  2. 首次看清体内所有癌症转移灶,深度学习方法立大功!中国留学生一作论文登《细胞》封面...
  3. mysql错误:this authentication plugin is not supported
  4. 如何获取服务器上文件的hashcode,java获取文件hashcode
  5. 2017计算机信息技术,2017年一级计算机信息技术及应用考试试题级答案[权威资料]...
  6. 利用shell和iptables实现自动拒绝恶意试探连接SSH服务
  7. 10-4-文章评论管理
  8. pythonjava有什么区别_Java与Python的区别对比
  9. 怎么把手机字体改成繁体_如何把手机字体变成繁体 繁体字转换器
  10. 中国石油大学(北京)-《 修井工程》第二阶段在线作业
  11. Java | PTA练习:Employee类的层级结构
  12. 何新生的英语史(八)—看好莱坞学英语,就是这么简单 1
  13. AARRR模型分析方法
  14. 苹果税要崩溃了!又一国家做出判决:iOS必须开放第三方支付
  15. MySQL 工作、底层原理
  16. 电脑录屏快捷键是什么?教你一招可以自己设定
  17. 易语言教程数据库替换
  18. 2022年全球市场艰难梭菌的分子诊断总体规模、主要生产商、主要地区、产品和应用细分研究报告
  19. 不看不知道 轿车制造成本大揭密
  20. 【菜鸟窝出品】 python的变量和逻辑基础(python数据分析入门)

热门文章

  1. Maven:解决jar包冲突和企业开发常用编写
  2. Linux基础命令---文本显示od
  3. linux和windows下忘记mysql密码的几种找回方法
  4. CLion之C++框架篇-安装工具,基础框架的搭建(一)
  5. ASP.NET MVC中的路由IRouteConstraint方法应用实例
  6. 不会Python开发的运维终将被淘汰?
  7. Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp
  8. php变量函数,回调函数
  9. Java和.NET互操作:应该放弃Web Service吗
  10. 计算机网络——标准化工作及相关组织