对一幅给定的图像(lena)加噪(椒盐噪声),分别用邻域平均和中值滤波方法滤波(不 能直接用函数实现),分析比较两种方法的差异及处理效果
时间: 2024-01-11 08:04:42 浏览: 99
用中值滤波滤除图像中的椒盐噪声.docx
好的,这是一个图像处理的问题。那么让我来帮您解答。
首先,我们需要导入一些必要的库,如下所示:
```python
import numpy as np
import cv2
import matplotlib.pyplot as plt
```
然后,我们可以读取给定的图像 lena,并添加椒盐噪声,如下所示:
```python
img = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)
h, w = img.shape[:2]
# 添加椒盐噪声
noise_ratio = 0.1
noise_num = int(h * w * noise_ratio)
for i in range(noise_num):
x = np.random.randint(0, w)
y = np.random.randint(0, h)
if np.random.rand() < 0.5:
img[y, x] = 0
else:
img[y, x] = 255
# 显示图像
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.title('Noisy Image')
plt.show()
```
接下来,我们可以实现邻域平均滤波方法。具体来说,我们可以定义一个滤波函数,该函数接受一个图像和滤波器的大小作为输入,并返回一个滤波后的图像。在该函数中,我们可以使用嵌套的循环来遍历整个图像,并在每个像素周围取一个固定大小的邻域,然后计算邻域中像素的平均值,并将该平均值赋给当前像素。具体实现如下所示:
```python
def mean_filter(img, kernel_size):
h, w = img.shape[:2]
padding_size = kernel_size // 2
img_pad = cv2.copyMakeBorder(img, padding_size, padding_size, padding_size, padding_size, cv2.BORDER_REPLICATE)
img_filtered = np.zeros((h, w), dtype=np.uint8)
for i in range(padding_size, h + padding_size):
for j in range(padding_size, w + padding_size):
roi = img_pad[i-padding_size:i+padding_size+1, j-padding_size:j+padding_size+1]
img_filtered[i-padding_size, j-padding_size] = np.mean(roi)
return img_filtered
```
最后,我们可以对加噪图像进行邻域平均滤波,并显示滤波后的图像,如下所示:
```python
kernel_size = 3
img_filtered_mean = mean_filter(img, kernel_size)
plt.imshow(img_filtered_mean, cmap='gray')
plt.axis('off')
plt.title('Mean Filtered Image')
plt.show()
```
接着,我们可以实现中值滤波方法。和邻域平均滤波类似,我们可以定义一个滤波函数,该函数接受一个图像和滤波器的大小作为输入,并返回一个滤波后的图像。在该函数中,我们可以使用嵌套的循环来遍历整个图像,并在每个像素周围取一个固定大小的邻域,然后计算邻域中像素的中值,并将该中值赋给当前像素。具体实现如下所示:
```python
def median_filter(img, kernel_size):
h, w = img.shape[:2]
padding_size = kernel_size // 2
img_pad = cv2.copyMakeBorder(img, padding_size, padding_size, padding_size, padding_size, cv2.BORDER_REPLICATE)
img_filtered = np.zeros((h, w), dtype=np.uint8)
for i in range(padding_size, h + padding_size):
for j in range(padding_size, w + padding_size):
roi = img_pad[i-padding_size:i+padding_size+1, j-padding_size:j+padding_size+1]
img_filtered[i-padding_size, j-padding_size] = np.median(roi)
return img_filtered
```
最后,我们可以对加噪图像进行中值滤波,并显示滤波后的图像,如下所示:
```python
kernel_size = 3
img_filtered_median = median_filter(img, kernel_size)
plt.imshow(img_filtered_median, cmap='gray')
plt.axis('off')
plt.title('Median Filtered Image')
plt.show()
```
最后,我们可以将三张图像 (原图像、添加椒盐噪声的图像、邻域平均滤波后的图像、中值滤波后的图像)进行对比,以便比较两种滤波方法的差异和处理效果,如下所示:
```python
plt.figure(figsize=(10, 10))
plt.subplot(221)
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.title('Original Image')
plt.subplot(222)
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.title('Noisy Image')
plt.subplot(223)
plt.imshow(img_filtered_mean, cmap='gray')
plt.axis('off')
plt.title('Mean Filtered Image')
plt.subplot(224)
plt.imshow(img_filtered_median, cmap='gray')
plt.axis('off')
plt.title('Median Filtered Image')
plt.show()
```
通过对比,我们可以发现,邻域平均滤波方法可以有效地去除图像中的椒盐噪声,但会使图像变得模糊;而中值滤波方法可以在不明显模糊图像的情况下有效地去除椒盐噪声。因此,在选择滤波方法时,需要根据具体情况进行选择。
阅读全文