SciPy - 中值滤波
SciPy 中的中值滤波
SciPy 中的 中值滤波 是一种非线性图像处理技术,用于去除噪声,特别是椒盐噪声,同时保留边缘。它的工作原理是将图像中每个像素替换为其周围邻域中的值的中值,该邻域可以是方形或矩形区域。
这种滤波器在平滑图像的同时不会模糊锐利边缘,因为与线性滤波器相比,它对异常值的敏感度较低。邻域大小可调,例如 3x3、5x5 等,常用于图像分析预处理阶段的去噪。
scipy 库的 scipy.ndimage 模块提供了一个名为 median_filter() 的函数,用于对给定图像应用中值滤波,以去除椒盐噪声,同时保留边缘细节。
语法
以下是 scipy.ndimage.median_filter() 函数的语法,用于应用中值滤波 −
scipy.ndimage.median_filter(input, size, footprint=None, output=None, mode='reflect', cval=0.0, origin=0)
以下是 scipy.ndimage.median_filter 的参数 −
- input: 将应用滤波的输入图像或数组。
- size: 邻域的大小,即元组或标量。如果是标量,则使用方形邻域,例如 3 表示 3x3 邻域。
- footprint(optional): 定义邻域形状的二进制数组。
- output(optional): 存储结果的数组。
- mode: 处理边界的方式,例如 'reflect'、'constant'、'nearest' 等。
- cval(optional): 当 mode='constant' 时使用的常数值。
- origin: 邻域的偏移量,默认值为 0。
中值滤波的工作原理?
在实现 中值滤波 以从图像中去除椒盐噪声时,需要遵循以下步骤 −
- 邻域选择: 对于每个像素,会考虑其周围像素的邻域。例如 3x3 或 5x5 网格。
- 中值计算: 计算该邻域中像素的中值。
- 像素替换: 用中值替换中心像素。
- 保留边缘: 中值滤波特别擅长去除噪声而不模糊图像中的锐利边缘。
中值滤波的优点
以下是在图像处理中使用中值滤波的优点 −
- 对椒盐噪声有效: 去除噪声的同时不会像线性滤波器那样模糊边缘。
- 非线性: 不依赖加权和,从而对异常值具有抵抗力。
中值滤波的局限性
中值滤波在使用时不仅有优点,还有一些局限性,可以列举如下 −
- 计算成本: 对于较大的邻域,中值滤波的计算成本可能高于线性滤波器。
- 边缘效应: 在图像边缘处,由于邻域大小受图像边界限制,该滤波器的性能可能不佳。
基本中值滤波器示例
以下示例展示了如何使用 scipy.ndimage.median_filter() 函数对 2D 图像或数组应用简单的 Median Filter,以去除噪声 −
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
# 示例 2D 图像 (5x5 网格)
image = np.array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]])
# 使用 3x3 邻域应用中值滤波器
filtered_image = ndimage.median_filter(image, size=3)
# 绘制原始图像和滤波后图像
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
axes[0].imshow(image, cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')
axes[1].imshow(filtered_image, cmap='gray')
axes[1].set_title('Median Filtered Image')
axes[1].axis('off')
plt.show()
以下是基本中值滤波器的输出 −
使用更大邻域的中值滤波器
此示例使用更大的邻域(如 5x5)进行中值滤波,以展示对更大区域的平滑效果 −
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
from skimage import data
# 加载示例图像
image = data.camera()
# 使用 5x5 邻域应用中值滤波器
filtered_image = ndimage.median_filter(image, size=5)
# 绘制原始图像和滤波后图像
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(image, cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')
axes[1].imshow(filtered_image, cmap='gray')
axes[1].set_title('Median Filtered (5x5) Image')
axes[1].axis('off')
plt.show()
以下是应用到更大邻域的中值滤波器输出 −
对 3D 图像应用中值滤波器
对 3D 图像应用中值滤波器与对 2D 图像应用类似,但在 3D 中,滤波器会在数据体积上工作,每个体素(3D 像素)被其在定义邻域内的中值所替换。
这对于去噪 3D 数据很有用,例如医学成像、模拟的体积数据或 3D 扫描数据。以下示例展示了一个使用中值滤波器处理的 3D 图像 −
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
# 创建合成 3D 图像 (10x10x10 数组)
image_3d = np.random.random((10, 10, 10))
# 使用 3x3x3 邻域应用中值滤波器
filtered_image_3d = ndimage.median_filter(image_3d, size=3)
# 绘制原始和滤波后的切片 (3D 可视化)
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(image_3d[5, :, :], cmap='gray') # 显示中间切片
axes[0].set_title('Original 3D Slice')
axes[0].axis('off')
axes[1].imshow(filtered_image_3d[5, :, :], cmap='gray') # 显示滤波图像的中间切片
axes[1].set_title('Median Filtered 3D Slice')
axes[1].axis('off')
plt.show()
以下是应用到 3D 图像的中值滤波器输出 −
