利用python的skimage库实现自适应中值滤波的改进算法对添加了椒盐和高斯噪声的lena图像进行去噪并可视化,然后输出峰值信噪比和均方误差,最后说明改进的自适应中值滤波算法的原理和相比中值滤波的改进之处、优点。请输出完整步骤的代码
时间: 2024-03-26 12:35:29 浏览: 63
好的,以下是完整的代码及注释说明:
```python
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, img_as_float
from skimage.filters import median, gaussian
from skimage.util import random_noise
# 读取lena图像并显示
img = img_as_float(io.imread('lena.png', as_gray=True))
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.show()
# 添加椒盐和高斯噪声并显示
img_salt_pepper = random_noise(img, mode='s&p', amount=0.05)
img_gaussian = random_noise(img, mode='gaussian', var=0.01)
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))
axes[0].imshow(img_salt_pepper, cmap='gray')
axes[0].set_title('Salt and Pepper Noise')
axes[1].imshow(img_gaussian, cmap='gray')
axes[1].set_title('Gaussian Noise')
plt.show()
# 自适应中值滤波的改进算法
def improved_adaptive_median_filter(img, max_size=11):
# 定义滤波器尺寸的初始值为3
size = 3
# 获取图像的行数和列数
rows, cols = img.shape
# 图像复制
img_filtered = img.copy()
# 对每个像素进行处理
for i in range(rows):
for j in range(cols):
# 根据当前滤波器尺寸计算出需要处理的区域
left = int(max(0, j - size / 2))
right = int(min(cols - 1, j + size / 2))
top = int(max(0, i - size / 2))
bottom = int(min(rows - 1, i + size / 2))
# 获取需要处理的像素值
values = img[top:bottom+1, left:right+1].flatten()
# 计算该区域的中位数和极差
median_val = np.median(values)
range_val = np.max(values) - np.min(values)
# 如果当前像素值落在区间[m - r, m + r]内,则对其进行中值滤波
if (median_val - range_val) < img[i, j] < (median_val + range_val):
img_filtered[i, j] = img[i, j]
# 否则将滤波器尺寸加1,直到达到最大尺寸
else:
size += 2
if size > max_size:
img_filtered[i, j] = median(values)
size = 3
return img_filtered
# 对添加了椒盐和高斯噪声的lena图像进行去噪并可视化
img_filtered_salt_pepper = improved_adaptive_median_filter(img_salt_pepper)
img_filtered_gaussian = improved_adaptive_median_filter(img_gaussian)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))
axes[0, 0].imshow(img_salt_pepper, cmap='gray')
axes[0, 0].set_title('Salt and Pepper Noise')
axes[0, 1].imshow(img_filtered_salt_pepper, cmap='gray')
axes[0, 1].set_title('Filtered Image')
axes[1, 0].imshow(img_gaussian, cmap='gray')
axes[1, 0].set_title('Gaussian Noise')
axes[1, 1].imshow(img_filtered_gaussian, cmap='gray')
axes[1, 1].set_title('Filtered Image')
plt.show()
# 计算峰值信噪比和均方误差
def psnr(img1, img2):
mse = np.mean((img1 - img2) ** 2)
if mse == 0:
return float('inf')
else:
return 10 * np.log10(1 / mse)
img_psnr_salt_pepper = psnr(img, img_filtered_salt_pepper)
img_psnr_gaussian = psnr(img, img_filtered_gaussian)
img_mse_salt_pepper = np.mean((img - img_filtered_salt_pepper) ** 2)
img_mse_gaussian = np.mean((img - img_filtered_gaussian) ** 2)
print('Salt and Pepper Noise:')
print('PSNR:', img_psnr_salt_pepper, 'dB')
print('MSE:', img_mse_salt_pepper)
print('Gaussian Noise:')
print('PSNR:', img_psnr_gaussian, 'dB')
print('MSE:', img_mse_gaussian)
```
该改进算法的原理是在自适应中值滤波的基础上,增加了对滤波器尺寸的动态调整。具体来说,对于每个像素,首先计算出当前滤波器尺寸所对应的区域的中位数和极差,如果该像素值落在区间[m - r, m + r]内,则对其进行中值滤波;否则将滤波器尺寸加1,直到达到最大尺寸。相比于传统的中值滤波,该改进算法可以更好地保留图像细节和边缘信息,同时避免了中值滤波的空间平滑效应,因此具有更好的去噪效果和图像质量。
阅读全文