高手常用的10大滤波方法,附赠示例程序,拿去直接用

文摘   科技   2024-08-16 17:30   山东  



在信号处理和数据分析领域,滤波算法扮演着至关重要的角色。它们帮助我们从嘈杂的数据中提取有用信息,平滑数据波动,预测未来趋势,甚至实现系统状态的精确估计。今天,我们将带您探索十大经典滤波算法,这些算法在工程实践和科学研究中都有着广泛的应用(获取案例程序的方法见文末)。


1. 限幅滤波:

  • 方法:

    • 如果新采样值与前一采样值之差小于或等于A,则认为本次采样有效。

    • 如果新采样值与前一采样值之差大于A,则认为本次采样无效,用前一次的有效采样值替代本次采样值。

  • 优点:

    抗脉冲干扰: 能够有效识别并排除由于瞬时干扰造成的异常采样值,从而保持数据的稳定性。


  • 缺点:

    • 周期性干扰抑制不足: 对于具有周期性的干扰,该算法可能无法有效识别和抑制,可能导致数据中存在周期性的波动。

    • 平滑度不足: 由于算法在遇到较大偏差时直接使用前一值替代,可能无法平滑处理数据中的波动,导致输出数据的平滑度不高。

//限幅滤波//如果新采样值与前一采样值之差小于或等于A,则认为本次采样有效。IF ABS(lrSignalIn - lrTemp) > lrDifference AND lrTemp <> 0 THEN    Filter_limit := lrTemp;ELSE  //如果新采样值与前一采样值之差大于A,则认为本次采样无效,用前一次的有效采样值替代本次采样值。    Filter_limit := lrSignalIn;END_IFlrTemp := lrSignalIn;

2. 算术平均滤波

  • 方法:

    • 取样:连续采集数据N次,并对这些数据求平均值

    • 求平均数:平均值的选取取决于N的大小

  • 优点:

    • 抗干扰能力: 适用于存在随机干扰的系统,通过多次采样求平均,能有效降低随机噪声的影响。

    • 稳定性: 通过平滑处理,提高了数据的稳定性和可靠性。

  • 缺点:

    • 处理速度: 由于需要连续采集并处理多次数据,算法的执行速度较慢。

    • 资源占用: 需要存储多次采样数据,因此占用较多的随机存取存储器(RAM)。

//算数平均滤波法//连续采集数据N次,并对这些数据求平均值FOR i := 0 TO iNumberOfSamples - 1 DO    aSampleBuffer[i] := lrSignalIn;END_FOR//输入值求和FOR j := 0 TO iNumberOfSamples - 1 DO    lrTempSum := lrTempSum + aSampleBuffer[j];END_FOR//求平均值Filter_average := lrTempSum / iNumberOfSamples;

3. 中位值滤波

  • 方法:

    • 排序:将数据点按照大小顺序进行排序

    • 选择中位值:从排序后的数据中选择位于中间位置的数值作为中位值。如果数据点数量是奇数,中位值就是正中间的数值;如果是偶数,则中位值通常是中间两个数值的平均值

    • 替换异常值:用中位值替换所有异常值或离群点

  • 优点:

    • 对异常值不敏感:中位值滤波法对异常值具有很好的抵抗力,不会像均值滤波那样受到极端值的影响

    • 适用于非线性数据:对于非线性或非高斯分布的数据,中位值滤波法仍然有效

  • 缺点:

    • 平滑能力有限:中位值滤波法主要用于去除异常值,对于平滑数据波动的能力有限

    • 对周期性噪声不敏感:中位值滤波法主要针对随机噪声有效,对于周期性或有结构的噪声可能不够有效

//中值滤波法//取样FOR icount :=0 TO iN DO  aSampleBuffer[icount]:= lrSignalIn ;END_FOR
//对样本缓冲区进行冒泡排序,以找到中位数 //外层循环控制排序的总轮数,每轮都会将最大的数移动到序列的末尾FOR j:=0 TO iN-1 DO //内层循环用于比较相邻元素并进行交换,以实现排序 FOR i:=0 TO iN-j DO //如果当前元素大于下一个元素,则交换它们 IF aSampleBuffer[i]> aSampleBuffer[i+1] THEN lrTemp := aSampleBuffer[i]; aSampleBuffer[i]:= aSampleBuffer[i+1]; aSampleBuffer[i+1]:= lrTemp ; END_IF END_FOREND_FOR//对于奇数个元素,直接取中间元素;对于偶数个元素,取中间两个元素的平均值,但这里只取了第一个中间值Filter_mid := aSampleBuffer[TO_INT((iN-1)/2)];

4. 限幅平均滤波

  • 方法:

    • 数据预处理:对每个采样点的信号值进行检查,如果超出限幅范围,则将其设置为限幅值(可以是上限或下限,取决于设计)。

    • 累加限幅后的数据:将经过限幅处理后的信号值进行累加。

    • 计算平均值:将累加的结果除以采样点的数量,得到限幅后的平均值

  • 优点:

    • 抑制异常值:有效抑制超出限幅范围的异常值或尖峰噪声。

    • 平滑信号:通过算术平均的方式平滑信号,减少随机噪声的影响。

    • 保持信号特征:在去除噪声的同时,能够较好地保持信号的原始特征

  • 缺点:

    • 可能引入失真:限幅处理可能会导致信号的部分信息丢失,引入一定程度的失真。

    • 对限幅值敏感:限幅值的选择对滤波效果有很大影响,不适当的限幅值可能导致有效信号被错误地限幅。

    • 对快速变化信号响应慢:由于平均的作用,滤波器对信号的快速变化响应较慢,可能无法及时跟踪信号的真实变化。

// 如果输入信号lrSignalIn与临时变量lrTemp的差的绝对值大于设定的阈值IF ABS(lrSignalIn - lrTemp) > lrDifference AND lrTemp <> 0 THEN    aSampleBuffer[i] := lrSignalIn;//将当前的输入信号lrSignalIn存储到样本缓冲区aSampleBuffer的第i个位置。  i := i+1;END_IFIF i >= iN THEN  // 如果索引i达到或超过样本缓冲区的最大索引iN,    // 则将i重置为0,实现循环缓冲的效果。  i := 0;END_IFlrSum := 0;FOR j:=0 TO iN DO  // 初始化求和变量lrSum为0,准备计算样本缓冲区所有元素的总和。    // 循环遍历样本缓冲区,从索引0到iN,累加每个元素的值到lrSum。  lrSum := lrSum + aSampleBuffer[j];END_FOR// 将当前的输入信号lrSignalIn赋值给临时变量lrTemp,准备用于下一次循环的比较。lrTemp := lrSignalIn;// 计算样本缓冲区所有样本的平均值Filter_limitav := lrSum / iN;

5. 消抖滤波

  • 方法:

    • 连续采样:对信号进行连续采样,获取一系列数据点。

    • 记录有效变化:如果连续采样值之间的差异超过阈值,则记录这次变化,并更新滤波后的输出。

    • 输出滤波结果:根据有效变化更新滤波后的信号输出。

  • 优点:

    • 抗干扰能力强:能有效滤除由于接触不良或传感器噪声引起的快速小幅度抖动。

    • 保持信号边缘:由于只忽略小幅度变化,消抖滤波通常能保持信号的快速上升或下降边缘。

    • 适用于开关信号:特别适用于处理开关信号或按钮输入,以消除误触发。

  • 缺点:

    • 参数选择关键:阈值的设定对滤波效果至关重要,不恰当的阈值可能导致有效信号被过滤掉或噪声被保留。

    • 可能延迟响应:由于需要等待超过阈值的变化,滤波器可能会引入一定的延迟。

    • 对大信号变化敏感:如果信号的实际变化超过阈值,可能会错误地认为是噪声而忽略,尤其是在信号变化复杂的情况下。

    • 不适合高频信号:对于高频信号,消抖滤波可能无法有效工作,因为它主要针对小幅度的随机变化。

//消抖滤波//// 如果当前信号值lrSignalIn不等于有效值lrValidIF lrSignalIn <> lrValid THEN  //将索引i增加1,用于跟踪信号变化的次数或时间  i := i + 1;  IF i > iN THEN    i := 0;    Filter_ditel := lrSignalIn;   END_IFELSE  // 如果当前信号值lrSignalIn等于有效值lrValid  i := 0;  // 将有效值lrValid赋值给滤波器  Filter_ditel := lrValid;END_IF

6. 限幅消抖滤波

  • 方法:

    限幅消抖滤波在消抖的基础上增加了限幅功能,通过设置上限和下限阈值来限制信号的波动范围。可以抑制更大范围的噪声,增强信号稳定性,适应性更强,有效防止信号失真,提高信号质量,应用场景更广泛。

//限幅消抖滤波//// 如果差值大于阈值,则将临时变量lrTemp设置为有效值lrValidIF ABS(lrSignalIn - lrValid) > lrDifference THEN  lrTemp := lrValid;ELSE  lrTemp := lrValid;END_IF// 如果计数器i超过设定的最大值iN,则重置i为0IF lrTemp <> lrSignalIn THEN  i := i + 1;  IF i > iN THEN    i := 0;    Filter_limitditel := lrValid;  END_IFEND_IF

7. 递推平均滤波

  • 方法:

    • 实时更新对于每一个新的输入数据点,使用以下递推公式更新滤波结果:

    • 连续应用:将上述递推公式连续应用于新的数据点,以实时更新滤波结果。

  • 优点:

    • 实时性:递推平均滤波法可以实时更新滤波结果,适合在线数据处理。

    • 计算效率高:由于只需要保留前一个滤波值,计算量小,适用于资源受限的系统。

    • 平滑效果:能够平滑数据中的随机噪声,使信号更加稳定。

  • 缺点:

    • 累积误差:长期应用递推公式可能导致误差累积,影响滤波精度。

    • 对初值敏感:滤波器的初始值对最终结果有一定影响,需要合理选择。

    • 无法处理突变:对于信号中的突变或跳变,递推平均滤波法可能无法及时响应。

//递推平均滤波// 将当前的信号值lrSignalIn存储到样本缓冲区aSampleBuffer的当前索引i位置aSampleBuffer[i]:= lrSignalIn;// 将索引i增加1,用于准备下一次数据的存储位置i:= i + 1;// 这通常用于循环缓冲区,当达到末尾时重新开始IF i>= iN THEN  i:= 0;END_IF// 遍历样本缓冲区aSampleBuffer中的所有样本FOR j:= 0 TO iN DO  lrTemp := lrTemp + aSampleBuffer[j];END_FOR// 计算移动平均值,即将累加的样本值除以缓冲区大小iNFilter_recav := lrTemp /iN ;

8.加权递推平均滤波

  • 特点:

    每个数据点根据其时间重要性被赋予一个权重。权重通常随着时间的增长而递减,这种加权机制允许滤波器对新数据给予更多的关注。

//加权递推平均滤波lrSumcoe :=0;// 将当前索引i转换为长实数并存储在加权系数数组aSumcoe中FOR i:= 0 TO iN DO  aSumcoe[i] :=TO_LREAL( i );  lrSumcoe :=lrSumcoe +i;END_FOR// 将信号值lrSignalIn赋值给样本缓冲区aSampleBuffer的每个位置FOR i :=0 TO iN DO  aSampleBuffer[i]:= lrSignalIn;END_FORlrSum :=0;// 遍历样本缓冲区aSampleBuffer,计算每个样本值与其对应加权系数的乘积FOR j:=0 TO iN DO  lrSum := lrSum + aSampleBuffer[i]*aSumcoe[i];END_FOR // 将加权后的样本值总和除以加权系数的总和,得到加权移动平均值IF lrSumcoe <> 0 THEN  Filter_recavwei := lrSum / lrSumcoe ;END_IF

9. 一阶滞后滤波法

  • 特点:

    一阶滞后滤波法(First-Order Lag Filter),也称为指数移动平均滤波法(Exponential Moving Average, EMA),是一种常用的信号平滑技术


  • 优点:

    • 简单高效:算法实现简单,计算效率高,适合实时数据处理。

    • 平滑性能好:能够有效地平滑随机噪声,提供信号的平滑估计。

    • 时间加权:对最近的数据赋予更高的权重,使得滤波结果更加反映近期趋势。

  • 缺点:

    • 对初值敏感:滤波器的初始值可能对最终结果有较大影响,特别是在数据序列的开始阶段。

    • 延迟效应:由于滞后效应,滤波后的信号会有一定的延迟,无法即时反映信号的突变。

    • 累积误差:在某些情况下,长时间使用可能导致误差累积,尤其是在信号特性发生变化时

//一阶滤波// 确保lrAlpha的值在0和1之间lrAlpha:=LIMIT(0,lrAlpha,1);// 根据一阶低通滤波器的公式计算滤波后的信号Filter_firstorder :=(1 - lrAlpha)* lrSignalIn + lrAlpha * lrTemp;lrTemp:= Filter_firstorder;

10. 卡尔曼滤波法

  • 方法:

    • 预测、更新:根据系统的动态模型预测下一状态,利用新的测量数据更新预测的状态

    • 卡尔曼增益:计算卡尔曼增益,它是一个权重,用于平衡预测值和观测值。

    • 递推更新:使用卡尔曼增益,结合预测值和观测值,递推更新估计的状态。


  • 优点:

    • 最优性:在高斯噪声假设下,卡尔曼滤波提供了最小均方误差的最优估计。

    • 递推性质:能够递推地更新状态估计,适合实时系统。

    • 鲁棒性:对于系统模型的不确定性和测量噪声具有一定的鲁棒性。

    • 通用性:适用于各种线性动态系统,也通过扩展(如扩展卡尔曼滤波和无迹卡尔曼滤波)用于非线性系统。

  • 缺点:

    • 高斯噪声假设:卡尔曼滤波基于高斯噪声的假设,对于非高斯噪声可能不是最优的。

    • 线性系统模型:标准的卡尔曼滤波适用于线性系统和线性观测模型,对于高度非线性系统需要使用扩展版本。

    • 敏感性:对初始状态估计和系统模型参数的准确性敏感,错误的参数可能导致次优的滤波性能。

    • 计算复杂度:对于具有大量状态变量的系统,计算协方差矩阵的更新可能具有较高的计算复杂度。

    • 稳定性问题:在某些情况下,如协方差矩阵非正定,卡尔曼滤波可能不稳定。

FUNCTION KalmanFilter2D : lrealVAR_INPUT      z: REAL;           // 测量值(位置)      intetime: REAL;          // 时间间隔      Q_pos: REAL;       // 位置过程噪声协方差      Q_vel: REAL;       // 速度过程噪声协方差      R_pos: REAL;       // 位置测量噪声协方差  END_VAR    VAR_OUTPUT      xHat: REAL;        // 估计的位置      vHat: REAL;        // 估计的速度  END_VAR    VAR      xHatPrev: REAL;    // 上一次的位置估计      vHatPrev: REAL;    // 上一次的速度估计      P_xx: REAL;        // 位置估计误差协方差      P_xv: REAL;        // 位置和速度估计误差协方差      P_vv: REAL;        // 速度估计误差协方差      K_x: REAL;         // 卡尔曼增益(针对位置)      K_v: REAL;         // (本例中不使用,但为了完整性保留)      P_xx_pred: REAL;    RP_xv_pred: REAL;     P_vv_pred: REAL;    S1: REAL;    v: REAL;      A_mat: ARRAY[1..2, 1..2] OF REAL;      Q_mat: ARRAY[1..2, 1..2] OF REAL;      C_mat: ARRAY[1..11..2] OF REAL;  END_VAR     // 初始化矩阵      A_mat[1,1] := 1; A_mat[1,2] := intetime;      A_mat[2,1] := 0; A_mat[2,2] := 1;        Q_mat[1,1] := Q_pos * intetime*intetime*intetime / 3 + Q_vel * intetime;      Q_mat[1,2] := Q_pos * intetime*intetime / 2;      Q_mat[2,1] := Q_pos * intetime*intetime / 2;      Q_mat[2,2] := Q_pos * intetime;        C_mat[1,1] := 1; C_mat[1,2] := 0;        // 预测步骤      xHatPrev := xHat;      vHatPrev := vHat + intetime * vHat; // 简化的速度预测(假设加速度为0)        // 协方差预测(这里简化了矩阵运算,实际中可能需要更复杂的处理)      P_xx_pred := P_xx + Q_mat[1,1];      RP_xv_pred := P_xv + Q_mat[1,2];      P_vv_pred := P_vv + Q_mat[2,2];        // 更新步骤(这里只更新位置相关的卡尔曼增益和状态)     S1 := P_xx_pred + R_pos;      K_x := P_xx_pred / S1;        xHat := xHatPrev + K_x * (z - xHatPrev);      vHat := v;
点赞+在看后,回复20240816获取程序源码


工控大侠
关注我,持续分享工控技术干货、行业动态!笔者20余年的自动化从业经验相信可以帮到您,有问题可留言。