滑动中值滤波算法详解

滑动中值滤波算法详解

1、什么是滑动中值滤波

滑动中值滤波(Moving Median Filter),属于非线性滤波,非常适合去除信号里的脉冲噪声、尖峰毛刺、跳变干扰,广泛用于传感器数据、嵌入式 ADC 采样、图像去噪。

核心思想:设置一个固定大小的滑动窗口,窗口沿着数据序列一步步向后滑动;把窗口内所有数据排序,取中位数作为当前点输出值。

和均值滤波区别:

  • 均值滤波:窗口取平均值,容易被异常大 / 小尖峰带偏,会抹平边缘突变
  • 中值滤波:取中位数,对孤立尖峰噪声免疫,保留信号阶跃边沿

2、原理举例
假设原始采样序列:[12, 13, 15, 120, 14, 11, 13]
窗口大小 window_size = 3(奇数,最常用)
窗口 1:[12,13,15] → 排序 [12,13,15] → 中位数 = 13
窗口 2:[13,15,120] → 排序 [13,15,120] → 中位数 = 15(120 尖峰直接被过滤掉)
窗口 3:[15,120,14] → 排序 [14,15,120] → 中位数 = 15
窗口 4:[120,14,11] → 排序 [11,14,120] → 中位数 = 14
窗口 5:[14,11,13] → 排序 [11,13,14] → 中位数 = 13
输出结果:[13,15,15,14,13]
可以看到 120 这个突变噪声直接消除,没有被平均稀释。
⚠窗口一般选奇数:3、5、7。偶数窗口需要取中间两数平均,工程很少用。

边界处理(重点)
原始信号开头、结尾,窗口不够数据:
截断模式(最简单嵌入式用):舍弃前后 (win‑size‑1)/2 个点,输出变短
复制填充:复制第一个 / 最后一个值补齐窗口
镜像填充:镜像复制边界数据(图像常用)
嵌入式单片机一般用截断模式。

3、优缺点
✅优点
抑制脉冲尖峰、跳变噪声效果极强,传感器跳变毛刺首选
保留阶跃、突变边沿,不会像均值滤波把跳变磨圆滑
逻辑简单,适合 STM32、ESP32 等嵌入式设备
❌缺点
对高斯白噪声抑制不如均值滤波
窗口越大,信号相位滞后(延迟)越大;窗口 N,会带来 (N‑1)/2 个采样点延迟
需要排序,窗口大的时候 CPU 开销上升
会把信号本身短暂真实尖峰一并滤掉(容易误删真实突变)
工程权衡:窗口不要盲目开大,一般传感器优先窗口 3/5。

4、滑动实现两种思路
方式 A:每次窗口全部重新排序(简单,小窗口首选)
窗口 3/5,每次滑动取出窗口内全部数据,sort 排序取中值。
代码最简单,嵌入式小窗口完全够用。
方式 B:滑动窗口维护有序队列(高效大窗口)
窗口向右滑动:删掉离开窗口的旧元素,插入新进来的元素,维持有序列表,直接取中间索引,避免每次完整排序。
适合窗口 7 以上,减少排序计算量。

5、Python 示例代码(简单重排版)

6、C 语言极简嵌入式版本(STM32 / 单片机可用,窗口 5)

#include <stdio.h>
#include <stdlib.h>

#define WINDOW 5
#define HALF_WIN (WINDOW/2)

// 简单冒泡排序
static void sort_buf(int *buf, int n)
{
for(int i=0;i<n;i++){
for(int j=0;j<n-1-i;j++){
if(buf[j]>buf[j+1]){
int t=buf[j];buf[j]=buf[j+1];buf[j+1]=t;
}
}
}
}

//输入原始数组,输出滤波数组
void moving_median_filter(int *in, int *out, int len)
{
int window[WINDOW];
int out_idx = 0;
// 边界截断,跳过开头HALF_WIN个点
for(int i=HALF_WIN; i < len-HALF_WIN; i++)
{
for(int k=0;k<WINDOW;k++){
window[k] = in[i - HALF_WIN + k];
}
sort_buf(window, WINDOW);
out[out_idx++] = window[HALF_WIN];
}
}

int main(void)
{
int raw[]={12,13,15,120,14,11,13,14,16};
int res[10]={0};
moving_median_filter(raw,res,9);
return 0;
}

单片机注意:窗口越大,排序耗时越高;ADC 实时采样,优先用窗口 3。

7、工程实操要点
窗口选择
偶尔尖峰毛刺:窗口 3
噪声频繁跳变:窗口 5
尽量避免 > 7,延迟大,CPU 负担重
与均值滤波组合:先中值去尖峰,再均值平滑白噪声,传感器常用组合滤波。
延迟问题:滑动中值会带来时间滞后,做闭环控制时,滞后会影响控制稳定性,控制场景谨慎开大窗口。
注意区分:
中值滤波:抑制脉冲噪声
均值滤波:抑制高斯噪声