4、图像滤波去噪:均值滤波、高斯滤波、中值滤波、双边滤波的原理与对比

图像滤波,说白了就是给图像「洗个澡」,把那些碍眼的噪点洗掉。我刚开始接触OpenCV时,觉得滤波不就是模糊一下嘛,有啥好学的?后来在工业检测项目里被噪点坑惨了,才老老实实回来补课。

今天咱们一口气聊透四种最常用的滤波方法:均值、高斯、中值、双边。它们各有脾气,用对了是神器,用错了就是灾难。

4.1 均值滤波:简单粗暴的「平均主义」

均值滤波的原理,你想想看,就是拿一个窗口在图像上滑动,把窗口内所有像素的亮度值加起来求个平均,然后用这个平均值替换窗口中心的像素值。

举个例子,一个3×3的窗口,里面有9个像素值,加起来除以9,就是新像素值。代码实现也特别直白:

import cv2
import numpy as np

img = cv2.imread('noisy_image.jpg')
# 均值滤波,核大小为5×5
blurred = cv2.blur(img, (5, 5))
cv2.imshow('Mean Filter', blurred)
cv2.waitKey(0)

嗯,这里要注意:cv2.blur()的第二个参数是元组,表示核的宽高。一般用奇数,比如3、5、7。为什么?因为奇数才有中心像素点。

⚠ 避坑指南: 我曾经在边缘检测前用了均值滤波,结果边缘全糊了。均值滤波会模糊边缘,因为它对所有像素一视同仁。如果你要保留边缘细节,慎用均值滤波。

4.2 高斯滤波:带权重的「温柔平均」

均值滤波有个问题——它把窗口内所有像素看得一样重。但你想啊,离中心越远的像素,对中心点的影响应该越小才对。高斯滤波就是来解决这个问题的。

它用高斯函数生成一个权重矩阵,离中心越近权重越大,离中心越远权重越小。然后拿这个权重矩阵去和图像做卷积。说白了,就是「加权平均」。

# 高斯滤波,核大小5×5,标准差1.5
gaussian = cv2.GaussianBlur(img, (5, 5), 1.5)
cv2.imshow('Gaussian Filter', gaussian)
cv2.waitKey(0)

第三个参数是标准差σ。σ越大,图像越模糊。我个人习惯先设σ=1.0,效果不够再加。为什么?因为σ太大,图像会像蒙了一层雾。

💡 小技巧: 高斯滤波是去除高斯噪声的首选。高斯噪声就是那种在图像上随机分布的、亮度变化符合正态分布的噪点。相机传感器在弱光环境下拍的照片,多半是这种噪声。

4.3 中值滤波:专治「椒盐噪声」的利器

椒盐噪声,就是图像上随机出现的白点和黑点,像撒了盐和胡椒。均值滤波和高斯滤波对这种噪声效果很差,因为噪声点的值太极端,一平均反而污染了周围像素。

中值滤波的思路完全不同——它把窗口内所有像素值排序,取中间那个值作为新像素值。你想想看,如果窗口里有个白点(255),周围都是正常值(比如100左右),排序后中间值大概率还是100左右,白点就被干掉了。

# 中值滤波,核大小为5
median = cv2.medianBlur(img, 5)
cv2.imshow('Median Filter', median)
cv2.waitKey(0)

注意参数是整数,不是元组。5表示5×5的窗口。我在项目中遇到过一张被椒盐噪声严重污染的X光片,均值滤波和高斯滤波都救不回来,中值滤波一上,效果立竿见影。

🔑 核心要点: 中值滤波对椒盐噪声效果极好,而且比均值滤波更能保留边缘。但它的计算量比均值滤波大,因为每次都要排序。不过对于现代计算机来说,小尺寸窗口完全不是问题。

4.4 双边滤波:既要降噪又要保边

前面三种滤波都有个通病——它们会模糊边缘。双边滤波就是来解决这个矛盾的。它的核心思想是:只有「空间上接近」且「像素值也接近」的像素才参与平均。

什么意思呢?比如你有一张照片,背景是墙,前景是人的脸。墙和脸的边界处,像素值差异很大。双边滤波在边界处会「聪明地」只取同一边的像素来平均,不会把墙和脸混在一起。

# 双边滤波,d=9,sigmaColor=75,sigmaSpace=75
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
cv2.imshow('Bilateral Filter', bilateral)
cv2.waitKey(0)

参数说明:d是窗口直径,sigmaColor是颜色空间的标准差,sigmaSpace是坐标空间的标准差。这两个σ值越大,滤波效果越强。

⚠ 注意: 双边滤波的计算量非常大。我曾经在实时视频处理中尝试用双边滤波,结果帧率直接掉到个位数。后来改用高斯滤波+边缘检测的组合方案,才勉强跑起来。所以,双边滤波适合离线处理,不适合实时场景。

4.5 四种滤波对比:什么时候用哪个?

我整理了一张对比表,方便你快速决策:

滤波方法 原理 适用噪声 边缘保留 计算速度 推荐场景
均值滤波 窗口内像素平均 高斯噪声(一般) 快速预览、噪声较轻
高斯滤波 加权平均(高斯权重) 高斯噪声(好) 一般 较快 通用降噪、预处理
中值滤波 窗口内像素取中值 椒盐噪声(极好) 较好 中等 椒盐噪声、扫描文档
双边滤波 空间+颜色双权重 各类噪声(好) 极好 美颜、保边降噪

4.6 实战建议:我的选择逻辑

在实际项目中,我一般按这个顺序来选:

  1. 先看噪声类型:如果是椒盐噪声,直接上中值滤波,别犹豫。
  2. 再看实时性要求:如果是实时视频,用高斯滤波,别碰双边滤波。
  3. 最后看边缘重要性:如果后续要做边缘检测或特征提取,优先考虑双边滤波或中值滤波。

我记得有一次做车牌识别,图像里有轻微的椒盐噪声。我一开始用高斯滤波,结果车牌字符的边缘被模糊了,识别率下降。换成中值滤波后,噪声没了,字符边缘也清晰,识别率直接提升15%。

💡 经验之谈: 滤波不是越强越好。有时候「轻度滤波」比「重度滤波」效果更好。我建议你先用小的核尺寸(比如3×3)试效果,不够再加。别一上来就搞个15×15,那图像基本就废了。

好了,四种滤波的原理和对比就聊到这儿。下一章咱们会讲形态学操作,到时候你会发现,滤波和形态学结合起来,能解决很多实际问题。