在图像处理与信号处理的应用中,我们经常会遇到各种噪声,例如“椒盐噪声”。为了去除这些干扰,中值滤波与均值滤波是两种常用且有效的滤波技术。
本文将通过图示+代码+案例,带你彻底理解它们的区别、实现方式与应用场景!
椒盐噪声(Salt-and-Pepper Noise)是一种图像中的随机噪声,表现为突兀的黑点和白点,就像图像被撒上了“盐粒”和“胡椒粒”。
原图像:
[34, 35, 36]
[33, 34, 38]
[32, 30, 29]
加入椒盐噪声后:
[34, 255, 36]
[0, 34, 255]
[32, 30, 0]
你可以看到一些像素点突然变成了 0(黑) 或 255(白),这就是典型的椒盐噪声。
对一个像素点,取其周围一定范围内的像素值,计算这些像素的平均值,并用这个值代替中心像素。
示例(3×3窗口):
[34, 35, 36]
[33, 100, 38]
[32, 30, 29]
平均值 = (34+35+36+33+100+38+32+30+29) / 9 = 40.8
→ 中间像素 100 → 替换为 41
算法简单,计算快速
能去除高斯噪声
对椒盐噪声无效
容易模糊边缘
取局部窗口内的所有像素值,将它们排序后取中值,用该中值替代中心像素。
示例(3×3窗口):
[34, 35, 36]
[33, 100, 38]
[32, 30, 29]
排序后:[29, 30, 32, 33, 34, 35, 36, 38, 100]
→ 中间像素 100 → 替换为 中值 34
对椒盐噪声非常有效
能较好保留图像边缘
计算比均值滤波复杂(需要排序)
对高斯噪声处理略逊
均值滤波(1D数组版):
float mean_filter(int* data, int size) {
float sum = 0;
for (int i = 0; i < size; i++) {
sum += data[i];
}
return sum / size;
}
中值滤波(1D数组版):
#include
int compare(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int median_filter(int* data, int size) {
int* temp = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++) temp[i] = data[i];
qsort(temp, size, sizeof(int), compare); // 排序
int median = temp[size / 2]; // 取中值
free(temp);
return median;
}
特性 | 中值滤波 | 均值滤波 |
---|---|---|
类型 | 非线性 | 线性 |
抗椒盐噪声 | ✅ 强 | ❌ 弱 |
保边缘能力 | ✅ 强 | ❌ 差 |
模糊图像 | ❌ 较少 | ✅ 明显 |
计算复杂度 | 中等(排序) | 低(加法) |
应用场景 | 推荐滤波器 |
---|---|
图像预处理 | 中值滤波 |
嵌入式图像采集 | 中值滤波 |
高斯噪声图像 | 均值滤波 |
摄像头信号清洗 | 中值滤波 |
实时低算力设备 | 均值滤波 |
中值滤波和均值滤波虽原理简单,但在图像处理、嵌入式信号清洗、机器人视觉等领域发挥着巨大作用。特别是在面对突发性噪声(如椒盐噪声)时,中值滤波是首选。
欢迎点赞、收藏、评论提问,我会持续更新嵌入式图像处理、滤波算法、蓝桥杯实战干货!