2. 中值滤波去除椒盐噪声
任务说明
本案例使用中值滤波对含椒盐噪声的图像进行去噪处理。椒盐噪声表现为图像中随机出现的白点(盐)和黑点(椒),中值滤波通过将每个像素替换为其邻域内所有像素的中值来去除这类孤立噪声点。案例目标为:生成含椒盐噪声的测试图像,应用中值滤波去噪,并与原图计算结构相似性指数(SSIM),同时观察滤波后图像边缘的保持情况。
实现原理与代码
中值滤波的核心思想是:对于图像中每个像素,取其周围邻域(如3×3或5×5窗口)内所有像素的灰度值,排序后取中间值作为该像素的新值。由于椒盐噪声是极端值(0或255),排序后不会落在中间位置,因此能被有效滤除;而边缘像素在邻域中仍能保持相对多数的一致性,故边缘信息得到较好保留。
以下代码使用Python和OpenCV实现完整流程:生成测试图像、添加椒盐噪声、应用中值滤波、计算SSIM并输出对比结果。
import cv2
import numpy as np
from skimage.metrics import structural_similarity as ssim
# 1. 生成测试图像(含清晰边缘的几何图形)
img = np.zeros((256, 256), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), 200, -1) # 白色方块
cv2.circle(img, (200, 200), 40, 150, -1) # 灰色圆形
cv2.line(img, (0, 0), (255, 255), 255, 3) # 白色对角线
# 2. 添加椒盐噪声(密度5%)
noise = np.random.rand(256, 256)
salt = noise > 0.975 # 盐噪声(白点)
pepper = noise < 0.025 # 椒噪声(黑点)
img_noisy = img.copy()
img_noisy[salt] = 255
img_noisy[pepper] = 0
# 3. 应用中值滤波(3×3窗口)
img_median = cv2.medianBlur(img_noisy, 3)
# 4. 计算SSIM(数据范围0-255)
ssim_value = ssim(img, img_median, data_range=255)
# 5. 输出结果
print(f"SSIM(原图 vs 中值滤波后): {ssim_value:.4f}")
print(f"SSIM(原图 vs 含噪图): {ssim(img, img_noisy, data_range=255):.4f}")
# 6. 保存结果图像
cv2.imwrite("original.png", img)
cv2.imwrite("noisy.png", img_noisy)
cv2.imwrite("median_filtered.png", img_median)
运行方式与依赖
需要安装Python 3及以下库:opencv-python、numpy、scikit-image。运行命令:python median_filter_demo.py。代码将生成三张PNG图像文件,并在终端打印SSIM数值。
验证方法与判定标准
运行后检查以下三点以判定案例通过:
- 去噪效果:打开
median_filtered.png,肉眼观察椒盐噪声点基本消失,图像干净; - 边缘保护:对比
original.png与median_filtered.png,方块、圆形和对角线的边缘轮廓清晰、无明显模糊或断裂; - SSIM指标:终端输出的SSIM(原图 vs 中值滤波后)应明显高于SSIM(原图 vs 含噪图),且通常大于0.9(具体值取决于噪声密度与图像内容,本案例中噪声密度5%时预期SSIM在0.95左右)。
预期输出说明
由于代码中使用了随机噪声生成,每次运行结果略有不同。在噪声密度5%条件下,预期SSIM(原图 vs 中值滤波后)约为0.95±0.02,而SSIM(原图 vs 含噪图)约为0.55±0.05。中值滤波后图像中椒盐噪声基本消除,几何图形的边缘轮廓保持完整,无明显模糊。上述数值为基于算法特性的理论预期,实际运行值可能因随机种子不同而略有波动,但滤波后SSIM显著高于含噪图SSIM这一趋势是确定的。