【C语言进阶日记】算法篇① 深入了解常用十二种滤波算法:原理、示例与应用

这篇具有很好参考价值的文章主要介绍了【C语言进阶日记】算法篇① 深入了解常用十二种滤波算法:原理、示例与应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

提示:滤波算法在信号处理和图像处理领域中广泛应用,可以用于去噪、平滑、增强和分析信号。本文将深入介绍滤波算法的原理和常见的应用,帮助读者更好地理解和使用滤波算法。


前言

滤波算法是一种数学技术,用于处理信号的频谱特性。通过对信号的时域或频域进行变换、修改和修复,可以达到不同的滤波效果。下面将介绍几种常见的滤波算法。


一、 限幅滤波算法

方法解析:根据经验判断,确定两次采样允许的最大偏差值(设定为A),每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效,如果本次值与上次值只差>A,则本次值无效,放弃本次值,用上次值代替本次值。
优点:能有效克服因偶然因素引起的脉冲干扰
缺点:无法抑制那种周期性的干扰,平滑度差

#define A 10  
char value;  
char filter()  
{  
   char  new_value;  
   new_value = get_ad();  
   if ( ( new_value - value > A ) || ( value - new_value > A )  
      return value;  
   return new_value;  
} 

二、中位值滤波法

中值滤波是一种非线性滤波算法,它通过将信号的像素值替换为相邻像素值的中值来去除图像中的椒盐噪声或快速噪声。中值滤波在去噪方面有着很好的效果,特别适用于图像处理领域。
方法解析:连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值
优点:能有效克服因偶然因素引起的波动干扰,对温度,液位的变化缓慢的被测参数有良好的滤波效果
缺点:对流量,速度等快速变化的参数不宜

#define N  11  
char filter()  
{  
   char value_buf[N];  
   char count,i,j,temp;  
   for ( count=0;count<N;count++)  
   {  
      value_buf[count] = get_ad();  
      delay();  
   }  
   for (j=0;j<N-1;j++)  
   {  
      for (i=0;i<N-j;i++)  
      {  
         if ( value_buf[i]>value_buf[i+1] )  
         {  
             temp = value_buf[i];  
     value_buf[i] = value_buf[i+1];   
             value_buf[i+1] = temp;  
         }  
      }  
   }  
   return value_buf[(N-1)/2];  
}  

三、算术平均滤波

方法解析:连续取N个采样值进行平均运算,N值较大时:信号平滑度较高,但灵敏度较低,N值较小时:信号平滑度较低,但灵敏度较高。N值的选取:一般12左右。
优点:适应于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
缺点:对于测量速度较慢或要求数据计算速度较快的实时控制并不适用,比较浪费RAM

#define N 12  
char filter()  
{  
   int  sum = 0;  
   for ( count=0;count<N;count++)  
   {  
      sum + = get_ad();  
      delay();  
   }  
   return (char)(sum/N);  

四、滑动窗口滤波器

移动平均滤波是最简单的滤波算法之一,它通过计算信号的均值来平滑信号。该算法适用于周期性或周期性变化较小的信号,可以有效降低噪声,并保留信号的趋势。
方法解析:把连续取N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出)。把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。N值的选取:一般12.
优点:对周期性干扰有良好的抑制作用,平滑度高,适应于高频振荡的系统
缺点:灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差。不易消除由于脉冲干扰所引起打的采样值偏差,不适用于脉冲干扰比较严重的场合浪费RAM

#define N 12   
char value_buf[N];  
char i=0;  
char filter()  
{  
   char count;  
   int  sum=0;  
   value_buf[i++] = get_ad();  
   if ( i == N )   i = 0;  
   for ( count=0;count<N,count++)  
      sum += value_buf[count];  
   return (char)(sum/N);  
}  

五、防脉冲干扰平均滤波法

方法解析:相当于中位值滤波+算术平均滤波,连续采样N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值。N值的选取:3-14
优点:融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。
缺点:测量速度较慢,和算法平均滤波一样,浪费RAM。

#define N 12  
char filter()  
{  
   char count,i,j;  
   char value_buf[N];  
   int  sum=0,temp=0;  
   for  (count=0;count<N;count++)  
   {  
      value_buf[count] = get_ad();  
      delay();  
   }  
   for (j=0;j<N-1;j++)  
   {  
      for (i=0;i<N-j;i++)  
      {  
         if ( value_buf[i]>value_buf[i+1] )  
         {  
             temp = value_buf[i];  
             value_buf[i] = value_buf[i+1];   
             value_buf[i+1] = temp;  
         }  
      }  
   }  
   for(count=1;count<N-1;count++)  
      sum += value[count];  
   return (char)(sum/(N-2));  
}

六、一阶滞后滤波法

方法解析:取a=0-1,本次滤波结果=(1-a)本次采样值+a上次滤波结果
优点:对周期性干扰具有良好的抑制作用,适用于波动频率较高的场合
缺点:相位滞后,灵敏度低,滞后程度取决于a值的大小,不能消除滤波频率高于采样频率的1/2的干扰信号

#define a 50  
char value;  
char filter()  
{  
   char  new_value;  
   new_value = get_ad();  
   return (100-a)*value + a*new_value;   
}  

七、加权递推平均滤波法

方法解析:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权,通常是,越接近现时刻的数据,权取得越大,给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。
优点:适用于有较大纯滞后时间常数的对象,和采样周期较短的系统
缺点: 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号,不能迅速反应系统当前所受干扰的严重程度,滤波效果差。

#define N 12  
char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};  
char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;  
char filter()  
{  
   char count;  
   char value_buf[N];  
   int  sum=0;  
   for (count=0,count<N;count++)  
   {  
      value_buf[count] = get_ad();  
      delay();  
   }  
   for (count=0,count<N;count++)  
      sum += value_buf[count]*coe[count];  
   return (char)(sum/sum_coe);  
}  

八、消抖滤波法

方法解析:设置一个滤波计数器,将每次采样值与当前有效值比较:
如果采样值=当前有效值,则计数器清零,如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出),如果计数器溢出,则将本次值替换当前有效值,并清计数器
优点:对于变化缓慢的被测参数有较好的滤波效果,可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。
缺点:对于快速变化的参数不宜,如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统

#define N 12  
char filter()  
{  
   char count=0;  
   char new_value;  
   new_value = get_ad();  
   while (value !=new_value);  
   {  
      count++;  
      if (count>=N)   return new_value;  
       delay();  
      new_value = get_ad();  
   }  
   return value;      
}  

九、低通数字滤波

解析:低通滤波也称一阶滞后滤波,方法是第N次采样后滤波结果输出值是(1-a)乘第N次采样值加a乘上次滤波结果输出值。可见a<<1。
该方法适用于变化过程比较慢的参数的滤波的C程序函数如下:

float low_filter(float low_buf[])  
{  
    float sample_value;  
    float X=0.01;  
    sample_value=(1-X)*low_buf[1]+X*low buf[0];  
    retrun(sample_value);  
} 

十、带通滤波

	// 输入信号
    float x[] = {};
    int n = sizeof(x) / sizeof(x[0]);

    // 滤波器系数
    float b[] = {};
    float a[] = {};
    int num = sizeof(b) / sizeof(b[0]);

    // 输出信号
    float y[n];

    // 滤波器算法
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            y[i] = b[i] * x[i];
        }
        else if (i < num && i > 0) {
            y[i] = 0.0;
            for (int j = 0; j <= i; j++) {
                y[i] += b[j] * x[j];
            }
            for (int j = 0; j < i; j++) {
                y[i] -= a[j] * y[j];
            }
        }
        else if (i >= num) {
            y[i] = 0.0;
            for (int j = 0; j < num; j++) {
                y[i] += b[j] * x[i-j];
            }
            for (int j = 0; j < num-1; j++) {
                y[i] -= a[j] * y[i-j-1];
            }
        }
    }

十一、卡尔曼滤波

卡尔曼滤波是一种递归滤波算法,广泛应用于估计和控制问题。它通过结合测量和预测的结果,利用系统动态模型和观测模型进行更新,可以准确估计信号的状态和测量值。

  double kalam_temp = 0.0;
  double p_temp = 0.0;
  double k = 0.0;

  if (true == firstFlag) {
    firstFlag = false;
    kalmanResult = moveAvgResult;
  } else {
    kalam_temp = kalmanResult;
    p_temp = pValue[0] + Q;

    k = p_temp / (p_temp + R);
    kalmanResult = kalam_temp + k * (moveAvgResult - kalam_temp);
    pValue[1] = (1 - k) * p_temp;
    // covariance P[] update
    pValue[0] = pValue[1];
  }
  // Kalman_buffer update
  kalman_result_buf[MG_HRM_ANALYSIS_NUM] = kalmanResult;
  for (uint8_t i = 0; i < MG_HRM_ANALYSIS_NUM; i++) {
    kalman_result_buf[i] = kalman_result_buf[i + 1];
  }

十二、小波变换滤波

小波变换滤波是一种时频分析方法,通过将信号分解为多个不同频率的小波系数,可对信号进行去噪、分解和重构。小波变换滤波具有多尺度分析的特点,适合处理非平稳信号。

 	int length = SIGNAL_LENGTH;
    int numCoeffs = wavelet_get_coeffs_length(length, LEVELS);
    double* coeffs = malloc(numCoeffs * sizeof(double));
  
    wavelet_transform(signal, length, coeffs, LEVELS, WAVELET_NAME);
    
    // 选择阈值进行信号去噪
    double threshold = wavelet_std_dev(coeffs, length, LEVELS) * sqrt(2 * log(length));
    
    // 对每个小波系数应用阈值
    for (int i = 0; i < length; i++) {
        if (fabs(coeffs[i]) < threshold * THRESHOLD_FACTOR) {
            coeffs[i] = 0.0;
        }
    }
    
    // 逆变换重构信号
    wavelet_inv_transform(reconstructedSignal, length, coeffs, LEVELS, WAVELET_NAME);
    

总结

本文介绍了滤波算法的原理和常见应用,涵盖了滑动窗口滤波器、中值滤波、卡尔曼滤波等。每种滤波算法都有其适用的场景和特点,读者可以根据实际需求选择合适的算法。同时也可以进一步学习和探索其他滤波算法,不断提升信号处理的技能和应用水平。

希望本文对大家了解滤波算法有所帮助!如有任何问题或建议,欢迎留言讨论。文章来源地址https://www.toymoban.com/news/detail-755018.html

到了这里,关于【C语言进阶日记】算法篇① 深入了解常用十二种滤波算法:原理、示例与应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 进阶JAVA篇-深入了解 List 系列集合

    目录         1.0 List 类的说明          1.1 List 类的常用方法         1.2 List 集合的遍历方式         2.0 ArrayList 集合的底层原理        2.1 从 ArrayList 集合的底层原理来了解具有该特性的原因:          2.2 ArrayList 集合的优缺点         3.0 LinkedList 集合的底层原理  

    2024年02月08日
    浏览(64)
  • 进阶JAVA篇-深入了解枚举与抽象枚举

    目录       介绍一下枚举:           1.1枚举的概念           1.2具体如何来使用呢?           1.3对枚举小结           1.4抽象枚举概念           1.5对抽象枚举小结         在JAVA中,枚举是一种特殊的类,用于定义一组常量。Java中的枚举类型是通过使用\\\"

    2024年02月07日
    浏览(49)
  • 大数据ClickHouse进阶(六):Distributed引擎深入了解

    文章目录 Distributed引擎深入了解 一、简单介绍 二、分布式表插入数据

    2024年01月15日
    浏览(36)
  • 【Java 进阶篇】深入了解 Bootstrap 全局 CSS 样式

    Bootstrap 是一个流行的前端框架,以其强大的全局 CSS 样式而闻名。这些样式能够帮助开发者快速创建漂亮的、响应式的网页,而无需从头编写复杂的 CSS。在本文中,我们将深入探讨 Bootstrap 的全局 CSS 样式,适合初学者,帮助他们更好地理解和应用这些样式。 全局 CSS 样式是

    2024年02月07日
    浏览(41)
  • 深入了解Git:介绍及常用命令指南

    当今软件开发领域中,版本控制是一个至关重要的概念,而Git作为最流行的分布式版本控制系统,发挥着不可替代的作用。本文将介绍Git的基本概念以及常用命令,帮助你更好地理解和使用这一强大的工具。 Git简介 Git是一种分布式版本管理系统(版本管理就是管理更新的历

    2024年02月11日
    浏览(38)
  • 进阶JAVA篇-深入了解 Stream 流对象的创建与中间方法、终结方法

    目录         1.0 Stream 流的说明         2.0 Stream 流对象的创建         2.1 对于 Collection 系列集合创建 Stream 流对象的方式         2.2 对于 Map 系列集合创建 Stream 流对象的方式         2.3 对于数组创建 Stream 流对象的方式         3.0 Stream 流的中间方法      

    2024年02月08日
    浏览(38)
  • 进阶JAVA篇-了解 File 文件的常用API

    🔥博客主页:  小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 目录         1.0 File 文件的说明         2.0 如何创建 File 类的对象         2.1 需要注意的事项         3.0 File 类的常用 API         3.1 如何创建文件或文件夹         3.2 如何查询文件和文件夹的信

    2024年02月06日
    浏览(34)
  • 【Java 进阶篇】用JSTL玩转Java:了解JSTL常用标签

    JavaServer Pages标准标签库(JavaServer Pages Standard Tag Library,简称JSTL)是Java Web应用程序中常用的标签库之一。它提供了一组标签,使得在JSP页面中处理数据、控制流程、以及显示内容变得更加便捷和高效。本文将带领你深入了解JSTL的常用标签,无论你是初学者还是有一定经验的

    2024年02月21日
    浏览(43)
  • c语言指针(深入了解指针)

    前沿:       有人曾说过不会指针等于没有学习c语言,而我也是非常认同这个观点的,要想学习好c语言,指针是比不可缺少的,如果指针学不会c语言也就没办法学好,而向如此越重要的东西越比较难学,但难学并不代表学不会,这片文章将由简单到复杂让你深刻的了解指针

    2023年04月08日
    浏览(48)
  • HTML :深入了解超文本标记语言

    欢迎来到本篇博客,我将带你深入了解 HTML(超文本标记语言)。作为前端开发的基础,HTML是构建网页的重要工具。在这里,我们将涵盖 HTML 的全部内容,包括常用语句和标签。 HTML,全称HyperText Markup Language,是一种用于创建网页结构的标记语言。它由一系列的标签组成,标

    2024年02月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包