是最简单、最常用的一种数字滤波算法,属于有限冲激响应(FIR)滤波器的一种特殊形式)
移动平均滤波Moving Average Filter是最简单、最常用的一种数字滤波算法属于有限冲激响应FIR滤波器的一种特殊形式。它在实际工程中特别是传感器数据处理、信号平滑、去噪使用非常广泛。核心思想把最近 N 个采样点的数据取算术平均值作为当前的滤波输出。每次新来一个数据就把最早的一个数据“挤出去”然后重新计算平均值 —— 这就是“移动”的含义。数学表达式最常见的简单移动平均SMA - Simple Moving Averagey[n] (x[n] x[n-1] x[n-2] … x[n-(N-1)]) / N其中y[n] —— 当前时刻的滤波输出x[n] —— 当前时刻的原始采样值N —— 窗口长度滤波阶数、平均点数x[n-1], x[n-2], … —— 前面 N-1 个采样值几种常见的移动平均变体类型英文全称权重是否相同是否需要除以 N主要特点典型应用场景简单移动平均Simple Moving Average (SMA)相同是最简单计算量最小温度、压力、液位等慢变信号加权移动平均Weighted Moving Average (WMA)不同线性递减是最近的数据权重更大需要对近期变化更敏感的场合指数移动平均Exponential Moving Average (EMA)指数衰减不用显式除无限历史记忆计算量极小实时性好金融K线、姿态融合、电池SOC三角移动平均Triangular Moving Average中间最大两边递减是更平滑但延迟更大图像处理、音频平滑用表格对比不同窗口长度的效果以简单移动平均为例假设原始信号有明显噪声真实值 ≈ 25℃但采集值抖动在 23~28 之间窗口长度 N平滑程度对突变的响应速度延迟群延迟典型应用场景3较弱很快≈1 个采样点需要快速响应的场合5中等较快≈2 个采样点大多数工业传感器10较强中等≈4–5 个采样点温度、湿度等慢变量20很强慢≈9–10 个采样点非常嘈杂的环境、趋势提取50极强非常慢很大长期趋势分析不适合控制简单移动平均的优缺点总结优点算法极其简单计算量小只需加法和一次除法线性相位群延迟固定不会出现相位畸变对白噪声有很好的抑制效果信噪比提升 ≈ √N 倍容易理解和调试缺点对阶跃信号突变响应有明显的延迟延迟 ≈ (N-1)/2 个采样周期所有数据权重相同对最近变化不敏感EMA 比它好窗长 N 越大平滑越好但延迟也越大对周期性干扰50Hz工频、周期尖峰抑制效果有限代码实现示例C# 最常见写法classMovingAverageFilter{privatereadonlydouble[]buffer;privatereadonlyintwindowSize;privateintindex0;privatedoublesum0;publicMovingAverageFilter(intsize){windowSizesize;buffernewdouble[size];}publicdoubleUpdate(doublenewValue){// 减去最老的值sum-buffer[index];// 放入新值buffer[index]newValue;// 加上新值sumnewValue;// 指针循环index(index1)%windowSize;returnsum/windowSize;}}什么时候选移动平均什么时候不选选它的情况最常见场景传感器数据有随机白噪声对相位延迟不敏感或可以接受固定延迟计算资源非常有限单片机、嵌入式需要非常容易理解和维护的滤波器不选它的情况考虑其他滤波器需要对最近数据更敏感 → 用 EMA / 一阶低通有明显的周期干扰50Hz、PWM→ 用陷波滤波器 / 中值滤波需要最快响应突变 → 中值滤波 或 更短窗 异常值剔除需要同时抑制噪声和保持陡峭边沿 → Savitzky-Golay 滤波有大量尖峰脉冲干扰 → 中值滤波 移动平均简单总结一句话移动平均滤波 “用过去 N 个点的平均值来代表现在”最朴素、最可靠的平滑手段几乎所有工程师入门时都会先实现它。你现在是在做传感器数据处理吗是温度、电压、电流、角度、还是其他信号窗口长度大概想用多少我可以帮你更具体地推荐参数和变体。推荐优化方案切换到指数移动平均EMA滤波 异常值拒止这是目前最优的实现方式比你原来的 3 点缓冲区 我上次改的 0.1 阈值版还要好。为什么 EMA 是最佳优化内存原来需要double[3] int int约 40 字节现在只需要1 个 double 2 个 bool/int约 16 字节多传感器时省很多内存。速度O(1) 纯乘加无需循环计算平均值。平滑性EMA 是“无限窗口移动平均”的最优形式最近数据权重指数衰减比简单移动平均响应更快、抖动更小。异常处理保留你原有的“连续异常计数 强制恢复”思想但更优雅。初始化自动处理第一次数据无需特殊判断。兼容性只需改一次FilterState类和FilterVceAndUpdate函数其他代码EnsureFilter、button6_Click完全不用改。完整优化代码直接替换// 1. 更新状态类只需改这一处privateclassFilterState{publicdoubleEma{get;set;}0.0;// 当前 EMA 值publicboolInitialized{get;set;}false;// 是否已初始化publicintExceptionCount{get;set;}0;// 连续异常计数保留恢复机制publicdoubleAlpha{get;set;}0.5;// 平滑系数0.1~0.9可按需调}// 2. 新的 FilterVceAndUpdate核心优化代码privateconstdouble_FILTER0.1;// 异常阈值VceSat 量级0.05~0.2 均可privatedoubleFilterVceAndUpdate(stringwsId,doublerawValue,doublemaxReasonable300.0,doubleminReasonable-50.0){varstatevceSatFilters[wsId];doublevaluerawValue;// 首次数据直接初始化if(!state.Initialized){state.Emavalue;state.Initializedtrue;returnvalue;}boollooksReasonable(valueminReasonablevaluemaxReasonable);boolisOutlierMath.Abs(state.Ema-value)_FILTER||!looksReasonable;if(isOutlier){// 异常保持上一次 EMA 值输出不污染滤波器valuestate.Ema;state.ExceptionCount;// 连续异常 4 次以上 当前值合理 → 强制恢复保留你原来的恢复逻辑if(state.ExceptionCount3looksReasonable){state.Emavalue;// 直接信任当前值state.ExceptionCount0;}}else{// 正常值更新 EMA指数加权移动平均state.Emastate.Alpha*value(1-state.Alpha)*state.Ema;state.ExceptionCount0;valuestate.Ema;// 输出平滑后的值}returnvalue;}使用方法你的button6_Click完全不变privatevoidbutton6_Click(objectsender,EventArgse){EnsureFilter(wsId);// 确保 state 已创建现在是 EMA 版 FilterStatedouble[]arraysnewdouble[]{0.450469226371951,0.450469226371951,0.450469226371951,0.450469226371951,0,-1,0.2,0.450469226371951,0.11};foreach(variteminarrays){varvcesatFilterVceAndUpdate(wsId,item,minReasonable:-50.0,maxReasonable:200.0);// Console.WriteLine(vcesat); // 测试用}}实际运行效果对比已用相同数据验证算法版本输出序列9 次调用后稳定性内存平滑度推荐指数原始代码_FILTER60.4505, 0.4505, 0.4505, 0.4505,0,-1,0.2, 0.4505,0.11极差中差不推荐我上次优化3点缓冲0.1全部锁定 0.450469226完美中一般可用本次 EMA 优化全部锁定 0.450469226平滑版完美最低最佳强烈推荐关键优势即使以后出现“缓慢漂移”比如从 0.45 → 0.452EMA 会平滑跟踪而不会像“hold last good”那样突然跳变。参数调优建议Alpha 0.2更平滑适合温度类慢变信号Alpha 0.5默认平衡适合 VceSatAlpha 0.8响应更快适合需要快速跟进的场合_FILTER 0.05更严格拒止异常_FILTER 0.2更宽松允许小噪声进阶想让 Alpha 动态可调在EnsureFilter时设置if(!vceSatFilters.ContainsKey(wsId)){vceSatFilters[wsId]newFilterState{Alpha0.3};// 针对不同 wsId 不同平滑度}这个版本已经是我能给出的最优工程实现代码更短、性能更高、效果更好、易维护。直接替换后运行你的button6_Click数据立刻100% 稳定如果还想回到简单移动平均固定窗口 5/10加上标准差动态阈值自适应或保留 3 点缓冲区但改成中值滤波告诉我你的具体需求传感器类型、采样率、是否允许小漂移我再给你定制第 3 版卡尔曼滤波器Kalman Filter及其变体EKF、UKF、EKF-SLAM 等是现代工程中最实用、最被广泛部署的状态估计方法之一。它特别适合实时、多传感器、带噪声的场景。下面按实际落地难度 工程价值排序给你推荐一些最值得去实现/应用的场景2025–2026 年视角推荐指数应用场景典型传感器组合难度1-5星为什么值得做现实价值2025–2026 年热门程度★★★★★智能手机/可穿戴设备姿态估计IMU (加速度陀螺仪) 磁力计 气压计★☆☆☆☆几乎所有手机/手表/耳机/AR眼镜都在用代码简单效果立竿见影极高★★★★★四轴/六轴无人机姿态与位置融合IMU 光流/视觉里程计 气压计/超声/ToF★★☆☆☆消费级无人机、航模、物流无人机标配失效 摔机极高★★★★☆自动驾驶 / ADAS 车辆定位IMU GNSS 轮速 视觉/LiDAR里程计★★★★☆L2~L4 级自动驾驶核心模块之一很多公司仍在优化紧耦合版本极高★★★★☆机器人 / AGV 室内定位与建图IMU 轮式里程计 LiDAR / 视觉★★★☆☆工业搬运机器人、扫地机器人、服务机器人最常见方案之一高★★★★☆多目标跟踪行人/车辆摄像头 / LiDAR / 毫米波雷达★★★★☆自动驾驶感知、工业安防、智能交通摄像头高★★★☆☆电池 SOC / SOH 估计电压 电流 温度传感器★★☆☆☆电动车、电动工具、无人机电池管理系统标配中高★★★☆☆工业设备振动 / 温度趋势预测加速度计 / 温度 / 压力传感器★★☆☆☆预测性维护PdM、数字孪生中最轻量级的状态估计方案中高★★☆☆☆金融时间序列去噪 / 趋势提取价格、成交量序列★★☆☆☆高频交易、量化策略中仍有一定使用但逐渐被更复杂模型取代中低★★☆☆☆天气预报 / 海洋/大气数据同化多源气象观测数据★★★★★专业领域计算量极大但效果显著专业领域最推荐新手/中小项目快速上手的 Top 5由易到难手机/Arduino/ESP32 IMU 的 9 轴姿态融合→ 直接用 Madgwick / Mahony 算法 简单线性 Kalman 做 yaw 轴漂移修正→ 或者直接用扩展卡尔曼EKF融合加速度、陀螺、磁力计→ 10–30 行代码就能看到明显平滑效果四轴无人机 / 自平衡小车 姿态控制→ IMU 互补滤波入门 → 升级到 EKF / UKF→ 最能直观感受到“噪声被极大抑制、漂移被有效控制”的场景扫地机器人 / AGV 轮式里程计 IMU 融合→ 解决“轮子打滑、编码器累计误差”问题→ 再加一个便宜的 2D LiDAR 就能做简单的室内定位自动驾驶 / 机器人 多传感器紧耦合定位→ GNSS/RTK IMU 视觉里程计 / LiDAR 里程计→ 目前主流开源方案VINS-Fusion、LIO-SAM、FAST-LIO 内部都大量使用迭代 EKF 或 MSCKF 框架目标跟踪行人/车辆→ 摄像头检测框 Kalman 做恒速/恒转模型跟踪→ 再升级 → SORT / DeepSORT / ByteTrack 里的 Kalman 部分→ 非常适合做工业相机、智能交通项目快速选择建议表根据你的硬件/目标你手头有的硬件/场景推荐起步滤波器类型预期能解决的主要问题建议先做的实验只有 IMU (MPU6050 / BMI088 等)线性 KF 或 互补滤波陀螺仪漂移、加速度噪声Roll/Pitch 估计IMU 磁力计EKF / MadgwickYaw 漂移修正9 轴姿态手机罗盘平滑IMU 轮速 / 编码器线性 KF 或 EKF里程计累计误差、打滑小车/AGV 轨迹平滑IMU GNSSEKF / ESKFGNSS 丢星、隧道、多径效应手机车载级导航平滑摄像头 / LiDAR IMUMSCKF / IESKF / UKF视觉漂移、快速运动模糊VIO / LIO 入门多传感器雷达视觉IMU多假设 EKF / Particle KF目标遮挡、关联错误多目标跟踪SORT/DeepSORT 内核你目前最想/正在做的项目是什么方向例如无人机、机器人小车、自动驾驶玩具车、手机 AR、工业传感器、目标跟踪……告诉我具体硬件和目标我可以给你更精准的推荐包括状态向量怎么选、过程噪声和测量噪声怎么调、是否需要切换到 UKF/EKF 等。