1. 基于OpenCV的简单均值滤波去噪
任务说明
本案例实现一个基于OpenCV的均值滤波去噪函数,输入一张含高斯噪声的手机照片,输出滤波后的去噪图像,并计算去噪前后的峰值信噪比(PSNR),用于量化评估去噪效果。
实现方案
均值滤波是线性空间滤波的典型方法,其核心思想是用邻域内所有像素的灰度平均值替代中心像素值,从而平滑噪声。本案例使用OpenCV的cv2.blur()函数实现均值滤波,并自定义PSNR计算函数,比较含噪图像与去噪图像的质量差异。PSNR值越高,表示去噪后图像与原始无噪图像越接近,去噪效果越好。
代码实现
import cv2
import numpy as np
def add_gaussian_noise(image, mean=0, sigma=25):
"""向图像添加高斯噪声"""
noise = np.random.normal(mean, sigma, image.shape).astype(np.uint8)
noisy = cv2.add(image, noise)
return noisy
def mean_filter_denoise(image, kernel_size=5):
"""均值滤波去噪"""
return cv2.blur(image, (kernel_size, kernel_size))
def calculate_psnr(original, denoised):
"""计算峰值信噪比PSNR(单位:dB)"""
mse = np.mean((original.astype(np.float64) - denoised.astype(np.float64)) ** 2)
if mse == 0:
return float('inf')
max_pixel = 255.0
psnr = 10 * np.log10((max_pixel ** 2) / mse)
return psnr
# 主流程
if __name__ == "__main__":
# 读取图像(请将photo.jpg替换为实际手机照片路径)
original = cv2.imread("photo.jpg")
if original is None:
raise FileNotFoundError("未找到图像文件,请检查路径")
# 转换为灰度图(简化处理,彩色图可对每个通道分别处理)
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
# 添加高斯噪声模拟手机拍摄噪声
noisy = add_gaussian_noise(gray, sigma=25)
# 均值滤波去噪
denoised = mean_filter_denoise(noisy, kernel_size=5)
# 计算PSNR
psnr_noisy = calculate_psnr(gray, noisy)
psnr_denoised = calculate_psnr(gray, denoised)
# 保存结果
cv2.imwrite("noisy.jpg", noisy)
cv2.imwrite("denoised.jpg", denoised)
# 打印结果
print(f"含噪图像 PSNR: {psnr_noisy:.2f} dB")
print(f"去噪图像 PSNR: {psnr_denoised:.2f} dB")
print(f"PSNR 提升: {psnr_denoised - psnr_noisy:.2f} dB")
运行与验证
依赖安装:确保已安装OpenCV和NumPy,执行pip install opencv-python numpy。
运行方式:将代码保存为mean_filter_denoise.py,将待处理的手机照片命名为photo.jpg放在同一目录下,执行python mean_filter_denoise.py。
验证方法:程序运行后,观察终端输出的PSNR值。若去噪图像的PSNR高于含噪图像,说明均值滤波有效抑制了噪声。同时可打开生成的denoised.jpg与noisy.jpg进行视觉对比,去噪图像应明显更平滑、噪声颗粒减少。
判定标准:当去噪后PSNR比含噪时提升3dB以上,且图像边缘细节保留可接受时,判定均值滤波去噪有效。不同噪声强度下,可调整kernel_size参数(如3、5、7)观察去噪效果与细节保留的平衡。