OpenCV(二十七):中值滤波

中值滤波(Median Filter)是一种在图像处理系统中被广泛采用的非线性滤波算法,主要用于去除脉冲噪声(Salt & Pepper Noise)和消除图像中的孤立噪点。相比均值滤波,中值滤波在保留边缘方面具有明显优势,因此在图像预处理阶段非常常用,如去噪、边缘检测前的降噪等。

椒盐噪声

椒盐噪声是一种典型的 脉冲噪声(Impulse Noise),表现为:

  • 随机出现的 极亮点(255,salt)
  • 极暗点(0,pepper)
  • 像素值与周围真实像素差异极大

例如:

正常像素值可能在 100~150 之间

但噪声可能突变为 0 或 255

特点:噪声像素是"异常值(Outlier)",比周围像素跳跃巨大。

这些极端值对线性滤波器(均值、高斯)影响很大,但对中值滤波影响很小。

基本原理

中值滤波属于典型的 基于排序统计(Order Statistics) 的非线性滤波方法。它的基本思想可以概括为:

取当前像素邻域内的所有像素值,排序后取中间的那个值作为输出像素。

假设我们使用一个 3×3 的滤波窗口,以图像中的一个像素 P 为中心,取其周围共 9 个像素,按灰度值从小到大排序:

例:周围像素为:

复制代码
23, 25, 90, 110, 120, 150, 155, 200, 255

排序后为:

复制代码
23, 25, 90, 110, 120, 150, 155, 200, 255

中间的那个值是第 5 个:120

因此,原中心像素 P 被替换为 120。

数学表达

设邻域为 Ω,邻域中的像素集合为:

排序后得到:

中值滤波输出为:

该公式说明中值滤波器利用排序统计特性,而不是线性加权求和,因此具有显著的抗噪声能力。

主要特点

优点

  • 对椒盐噪声(黑白强干扰点)尤其有效
    中值滤波几乎是去除椒盐噪声的最佳选择,能在不明显模糊图像的情况下有效抑制异常值。
  • 比均值滤波更好地保留边缘
    因为不进行像素平均,因此边缘不会被模糊。
  • 简单稳定、计算量适中,适合实时处理

缺点

  • 对高斯噪声等连续噪声不如均值滤波有效;
  • 大窗口中值滤波会丢失细节;
  • 排序操作在大窗口下计算较耗时,但现代 CPU/GPU 差距不明显。

适用场景

  1. 处理含椒盐噪声的监控视频或拍照图像
  2. 图像边缘检测前的预降噪
  3. 医学影像预处理(如 MRI、CT 图像)
  4. 道路识别、车牌识别等需要保护边缘的场景
  5. 去除图像孤立亮点或黑点

OpenCV中的中值滤波函数

OpenCV 提供的函数为:

python 复制代码
cv2.medianBlur(src, ksize)

参数说明:

  • src:原始图像;
  • ksize:核大小,只能是 奇数,例如 3、5、7...;
  • 输出图像与输入图像大小相同。

注意:ksize 必须是奇数且 ≥ 3

原因在于:

  • 奇数才有唯一的中间值;
  • 核大小越大,滤波越强,但可能损失更多细节。

示例

去除椒盐噪声

python 复制代码
import cv2
import numpy as np

img = cv2.imread('input.jpg', 0)  # 灰度图
noise = img.copy()

# 添加椒盐噪声
salt_pepper_prob = 0.02
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        r = np.random.rand()
        if r < salt_pepper_prob:
            noise[i][j] = 0       # 黑点
        elif r > 1 - salt_pepper_prob:
            noise[i][j] = 255     # 白点

# 中值滤波处理
denoised = cv2.medianBlur(noise, 5)

cv2.imshow("Salt&Pepper Noise", noise)
cv2.imshow("Denoised by Median", denoised)
cv2.waitKey(0)

执行效果:

与均值滤波、高斯滤波对比

python 复制代码
import cv2

img = cv2.imread('test.jpg')

# 均值滤波
mean = cv2.blur(img, (5,5))

# 高斯滤波
gaussian = cv2.GaussianBlur(img, (5,5), 1)

# 中值滤波
median = cv2.medianBlur(img, 5)

cv2.imshow('Original', img)
cv2.imshow('Mean Blur', mean)
cv2.imshow('Gaussian Blur', gaussian)
cv2.imshow('Median Blur', median)
cv2.waitKey(0)

效果对比:

  • 均值滤波:图像变模糊,边缘损伤严重;
  • 高斯滤波:去噪柔和,但仍会模糊边缘;
  • 中值滤波:保边效果最明显。
相关推荐
kisshuan1239620 小时前
【深度学习】使用RetinaNet+X101-32x4d_FPN_GHM模型实现茶芽检测与识别_1
人工智能·深度学习
Learn Beyond Limits20 小时前
解构语义:从词向量到神经分类|Decoding Semantics: Word Vectors and Neural Classification
人工智能·算法·机器学习·ai·分类·数据挖掘·nlp
崔庆才丨静觅21 小时前
0代码生成4K高清图!ACE Data Platform × SeeDream 专属方案:小白/商家闭眼冲
人工智能·api
qq_3564483721 小时前
机器学习基本概念与梯度下降
人工智能
水如烟1 天前
孤能子视角:关系性学习,“喂饭“的小孩认知
人工智能
徐_长卿1 天前
2025保姆级微信AI群聊机器人教程:教你如何本地打造私人和群聊机器人
人工智能·机器人
XyX——1 天前
【福利教程】一键解锁 ChatGPT / Gemini / Spotify 教育权益!TG 机器人全自动验证攻略
人工智能·chatgpt·机器人
十二AI编程1 天前
Anthropic 封杀 OpenCode,OpenAI 闪电接盘:AI 编程生态的 48 小时闪电战
人工智能·chatgpt
CCC:CarCrazeCurator1 天前
从 APA 到 AVP:汽车自动泊车系统技术演进与产业发展深度研究
人工智能