空间滤波是一种基于像素点周围邻域像素灰度值的加权平均来处理图像的方法。该方法在图像处理领域被广泛应用,包括图像增强、去噪、边缘检测等方面。
空间滤波的效果取决于滤波器的大小和权重系数的选择。滤波器越大,可以平滑更大的区域,但会使得图像细节信息丢失得更多。权重系数的选择也是一项挑战,不同的权重系数可以导致不同的滤波效果,需要根据具体应用场景进行调整。
将像素点周围邻域的灰度值取平均值作为中心像素的新灰度值。该方法可以平滑图像,去除噪声,但会使得图像细节信息变得模糊。
o u t p u t ( x , y ) = 1 k 2 ∑ i = x − k − 1 2 x + k − 1 2 ∑ j = y − k − 1 2 y + k − 1 2 i n p u t ( i , j ) \mathrm{output}(x, y) = \frac{1}{k^2} \sum_{i=x-\frac{k-1}{2}}^{x+\frac{k-1}{2}} \sum_{j=y-\frac{k-1}{2}}^{y+\frac{k-1}{2}} \mathrm{input}(i, j) output(x,y)=k21i=x−2k−1∑x+2k−1j=y−2k−1∑y+2k−1input(i,j)其中, k k k是滤波器的大小, i n p u t ( i , j ) \mathrm{input}(i, j) input(i,j)是输入图像在坐标 ( i , j ) (i,j) (i,j)处的像素值, o u t p u t ( x , y ) \mathrm{output}(x,y) output(x,y)是输出图像在坐标 ( x , y ) (x,y) (x,y)处的像素值。公式中的两个嵌套求和表示对输入图像的一个 k × k k \times k k×k大小的邻域进行求和,然后除以 k 2 k^2 k2得到该邻域的平均值,作为输出图像在 ( x , y ) (x,y) (x,y)处的像素值。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取彩色图像
img = cv2.imread('example.jpg')
# 添加高斯噪声
mean = 0
var = 0.5
sigma = var ** 0.5
gaussian = np.random.normal(mean, sigma, img.shape)
noisy_img = np.clip((img/255.0 + gaussian)*255, 0, 255).astype(np.uint8)
# 使用不同大小的卷积核进行均值滤波
k_sizes = [3, 13, 23, 33] # 卷积核大小
fig, axs = plt.subplots(1, 6, figsize=(12, 3))
axs[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
axs[0].set_title("Original")
axs[1].imshow(cv2.cvtColor(noisy_img, cv2.COLOR_BGR2RGB))
axs[1].set_title("Noisy")
for i, ksize in enumerate(k_sizes):
# 使用均值滤波器进行处理
denoised_img = cv2.blur(noisy_img, (ksize, ksize))
# 显示处理后的图像
axs[i+2].imshow(cv2.cvtColor(denoised_img, cv2.COLOR_BGR2RGB))
axs[i+2].set_title(f"Denoised (ksize={ksize})")
plt.tight_layout()
plt.show()
从实验结果可以看出,均值滤波器的卷积核尺寸越大,去噪强度越高,但同时图像也越模糊。
将像素点周围邻域的灰度值排序,取中间值作为中心像素的新灰度值。该方法可以去除椒盐噪声等非常规噪声,但会使得图像细节信息变得模糊。
import numpy as np
import matplotlib.pyplot as plt
import cv2
import random
# 添加椒盐噪声
def pepper_and_salt(img, percentage):
num = int(percentage * img.shape[0] * img.shape[1]) # 椒盐噪声点数量
img2 = img.copy()
for _ in range(num):
X = random.randint(0, img2.shape[0] - 1)
Y = random.randint(0, img2.shape[1] - 1)
if random.randint(0, 1) == 0: # 黑白色概率55开
img2[X, Y] = (255, 255, 255)
else:
img2[X, Y] = (0, 0, 0)
return img2
# 读取彩色图像
img = cv2.imread('example.jpg')
noisy_img = pepper_and_salt(img, 1.0)
blur_mean = cv2.blur(noisy_img, ksize=(5, 5))
blur_median = cv2.medianBlur(noisy_img, ksize=5)
# 显示原始图像、噪声图像和滤波后的图像
fig, axs = plt.subplots(1, 4)
axs[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
axs[0].set_title('Original')
axs[1].imshow(cv2.cvtColor(noisy_img, cv2.COLOR_BGR2RGB))
axs[1].set_title('Noisy')
axs[2].imshow(cv2.cvtColor(blur_mean, cv2.COLOR_BGR2RGB))
axs[2].set_title('Mean Filtered')
axs[3].imshow(cv2.cvtColor(blur_median, cv2.COLOR_BGR2RGB))
axs[3].set_title('Median Filtered')
plt.show()
从实验结果可以看出,相比均值滤波,中值滤波能够更有效地去除椒盐噪声。
利用高斯函数对像素点周围邻域的灰度值进行加权平均,使得离中心像素越远的像素权重越小。该方法能够平滑图像,去除高斯噪声,同时保留图像边缘信息。
该方法保留了图像中的边缘信息,通过对滤波器的设计,可以达到去除噪声和保留边缘的双重效果。