4. 图像滤波与去噪:均值滤波、高斯滤波、中值滤波、双边滤波的原理与OpenCV实现

图像滤波,说白了就是给图像做「磨皮」或者「去杂质」。在工业现场,相机拍回来的图很少是干干净净的——传感器噪声、光照不均、传输干扰,都会让图像带上各种噪点。如果不处理,后续的检测、测量、识别全都会受影响。

我个人习惯把滤波分成两类:线性滤波和非线性滤波。均值、高斯属于前者,中值、双边属于后者。下面一个一个讲清楚。

核心观点:没有万能的滤波器。选哪种,取决于你的噪声类型和任务目标。
图像滤波与去噪知识体系 图像滤波 线性滤波 非线性滤波 均值滤波 邻域像素取平均 高斯滤波 加权平均,中心权重高 中值滤波 取邻域中位数 双边滤波 保边去噪 应用场景:去噪 / 平滑 / 边缘保留 / 预处理 💡 选型建议 高斯噪声 → 高斯滤波 / 均值滤波 椒盐噪声 → 中值滤波 需要保边 → 双边滤波

4.1 均值滤波

均值滤波的原理最简单:用一个窗口扫过图像,窗口内所有像素取平均值,作为中心像素的新值。

举个例子,一个 3×3 的窗口,9 个像素值加起来除以 9,就是新值。窗口越大,平滑效果越强,但图像也越模糊。

我的经验:均值滤波在工业上用得越来越少。因为它「一视同仁」,把边缘和噪声一起模糊了。除非你只是做粗略的降采样预处理,否则我建议你优先考虑高斯滤波。
import cv2
import numpy as np

img = cv2.imread('industrial_part.jpg', cv2.IMREAD_GRAYSCALE)

# 均值滤波:ksize 必须是奇数
blur_3 = cv2.blur(img, (3, 3))
blur_5 = cv2.blur(img, (5, 5))
blur_9 = cv2.blur(img, (9, 9))

你看,代码就一行。但参数 ksize 很关键。3×3 基本不损失细节,但去噪能力有限;9×9 去噪强,但边缘也糊得差不多了。我一般从 5×5 开始试。

4.2 高斯滤波

高斯滤波和均值滤波的区别在于「权重」。均值滤波是平均主义,高斯滤波是「中心说了算」——离中心越近的像素权重越大,权重由高斯函数决定。

为什么这样更好?因为自然图像中,中心像素和周围像素的相关性本来就更高。高斯滤波更符合直觉,效果也更自然。

关键参数:ksize(核大小)和 sigmaX(标准差)。sigma 越大,权重分布越平缓,平滑效果越强。
# 高斯滤波
gauss_3 = cv2.GaussianBlur(img, (3, 3), sigmaX=0)
gauss_5 = cv2.GaussianBlur(img, (5, 5), sigmaX=1.0)
gauss_9 = cv2.GaussianBlur(img, (9, 9), sigmaX=2.0)

这里有个小细节:sigmaX=0 时,OpenCV 会根据核大小自动计算 sigma。我个人习惯手动指定 sigma,因为控制感更强。

避坑:我曾经在一个 PCB 检测项目里,直接用默认参数做高斯滤波,结果把细小的焊盘边缘给磨没了。后来把 sigma 从 1.5 降到 0.8,问题解决。记住:去噪和保边永远是 trade-off。

4.3 中值滤波

中值滤波是非线性滤波的代表。它不取平均,而是取窗口内所有像素的中位数作为新值。

为什么中值滤波对椒盐噪声特别有效?你想想看,椒盐噪声是极亮或极暗的像素点,取中位数时这些极端值根本排不上号,直接被忽略掉了。

# 中值滤波
median_3 = cv2.medianBlur(img, 3)
median_5 = cv2.medianBlur(img, 5)

注意:中值滤波的核大小只用一个数字,因为窗口是正方形的。而且它必须用奇数,3、5、7……道理很简单,奇数个数字才有唯一的中位数。

我的习惯:在工业视觉中,如果图像有明显的椒盐噪声(比如传感器坏点、传输丢包),我第一反应就是中值滤波。它不会模糊边缘,这是它比均值和高斯强的地方。

4.4 双边滤波

双边滤波是「既要又要」的典型代表——既要平滑噪声,又要保留边缘。它怎么做到的?

双边滤波在计算权重时考虑两个因素:

  • 空间距离:离中心越近,权重越大(和高斯一样)
  • 像素值差异:和中心像素值越接近,权重越大

这样一来,在平坦区域,双边滤波像高斯一样平滑;但在边缘处,像素值差异大,边缘另一侧的像素权重被压低,边缘就保住了。

# 双边滤波
# d: 邻域直径,sigmaColor: 颜色标准差,sigmaSpace: 空间标准差
bilateral = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
参数解读:
  • d:窗口直径。越大,考虑的范围越广,计算越慢。
  • sigmaColor:颜色差异的容忍度。越大,越多的颜色差异被平滑掉。
  • sigmaSpace:空间距离的权重。越大,远处的像素影响越大。

双边滤波的缺点也很明显——慢。在工业实时场景下,如果图像分辨率高,双边滤波可能成为瓶颈。我曾经在一个 500 万像素的检测项目里试过双边滤波,一帧处理了 200 多毫秒,根本跑不到 30fps。后来换成了引导滤波才解决。

4.5 四种滤波对比总结

滤波器 类型 去噪效果 边缘保留 计算速度 适用噪声
均值滤波 线性 一般 差 快 高斯噪声
高斯滤波 线性 较好 一般 快 高斯噪声
中值滤波 非线性 好(椒盐) 好 中等 椒盐噪声
双边滤波 非线性 好 极好 慢 高斯噪声 + 保边

4.6 实战建议:如何选择滤波器

在工业视觉项目中,我一般按这个流程来选:

  1. 先看噪声类型:如果是椒盐噪声(黑白点),直接上中值滤波。如果是高斯噪声(整体颗粒感),用高斯滤波。
  2. 再看任务需求:如果后续要做边缘检测或测量,必须保边,那就用双边滤波或中值滤波。如果只是做图像增强前的预处理,高斯滤波就够了。
  3. 最后考虑速度:实时检测场景(比如 30fps 以上),双边滤波基本不用想。中值滤波在核大小不超过 5 时还能接受。
我曾经踩过的坑:在一个锂电池极片缺陷检测项目中,我一开始用了双边滤波保边,结果因为参数没调好,把微小的划痕也给平滑掉了。后来改用中值滤波 + 小核高斯组合,才把缺陷保留下来。所以,不要迷信某个滤波器,组合使用往往效果更好。

嗯,滤波这部分就讲到这里。记住一句话:没有最好的滤波器,只有最合适的滤波器。多试几个参数,多看看效果图,你自然就有感觉了。