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)

效果对比:

  • 均值滤波:图像变模糊,边缘损伤严重;
  • 高斯滤波:去噪柔和,但仍会模糊边缘;
  • 中值滤波:保边效果最明显。
相关推荐
风象南4 小时前
我把大脑开源给了AI
人工智能·后端
Johny_Zhao6 小时前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
飞哥数智坊6 小时前
我帮你读《一人公司(OPC)发展研究》
人工智能
冬奇Lab10 小时前
OpenClaw 源码精读(3):Agent 执行引擎——AI 如何「思考」并与真实世界交互?
人工智能·aigc
没事勤琢磨12 小时前
如何让 OpenClaw 控制使用浏览器:让 AI 像真人一样操控你的浏览器
人工智能
用户51914958484512 小时前
CrushFTP 认证绕过漏洞利用工具 (CVE-2024-4040)
人工智能·aigc
牛马摆渡人52812 小时前
OpenClaw实战--Day1: 本地化
人工智能
前端小豆12 小时前
玩转 OpenClaw:打造你的私有 AI 助手网关
人工智能
BugShare12 小时前
写一个你自己的Agent Skills
人工智能·程序员
机器之心13 小时前
英伟达护城河被AI攻破,字节清华CUDA Agent,让人人能搓CUDA内核
人工智能·openai