文章目录
1. 概述
图像空间滤波是一种常用的图像处理技术,用于改变图像的亮度、对比度、锐度、噪声等特性。它是一种直接在图像空间进行像素操作的处理方法,与频域滤波不同,频域滤波是通过对图像进行傅里叶变换,然后在频域进行滤波处理。本文仅对常用的低通和高通空间滤波进行概括和总结。
2 低通(平滑)滤波
2.1 均值滤波
假设均值滤波器的大小为 n × n n\times n n×n,则该卷积核可以表示为如下的 n × n n\times n n×n 矩阵:
1 n 2 ( 1 1 ⋯ 1 1 1 ⋯ 1 ⋮ ⋮ ⋱ ⋮ 1 1 ⋯ 1 ) \frac{1}{n^2} \begin{pmatrix} 1 & 1 & \cdots & 1 \\ 1 & 1 & \cdots & 1 \\ \vdots & \vdots & \ddots & \vdots \\ 1 & 1 & \cdots & 1 \\ \end{pmatrix} n21
11⋮111⋮1⋯⋯⋱⋯11⋮1
其中,矩阵中的每个元素都是 1 / n 2 1/n^2 1/n2,表示该像素点的权重值等于周围所有像素点的权重之和的平均值。这样,在卷积操作时,该卷积核将对图像中的每个像素点取周围像素点的平均值,从而实现平滑处理。
需要注意的是,均值滤波器的大小 n n n 越大,滤波器的平滑程度越强,但也可能会导致图像细节的丢失。因此,在实际应用中需要根据具体的需求和图像特点选择合适的滤波器大小。
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()

从实验结果可以看出,均值滤波器的卷积核尺寸越大,去噪强度越高,但同时图像也越模糊。
2.2 中值滤波
中值滤波的原理是将像素点周围的邻域中的像素灰度值排序,然后取中间值作为该像素的灰度值。由于中值滤波是一种非线性滤波方法,其不受噪声分布的影响,可以有效地去除图像中的椒盐噪声和斑点噪声,并且可以保留图像的边缘信息和细节信息。
中值滤波的具体操作步骤如下:
- 选定滤波器的大小,通常取一个奇数的正整数,如 3 × 3 3 \times 3 3×3、 5 × 5 5 \times 5 5×5 等。
- 针对每个像素点,将其周围的邻域像素点的灰度值排序,从小到大排列。
- 取排序后的中间值作为该像素点的新灰度值。
- 对于边缘上的像素,可以选择对其不做处理或者根据需要进行特殊处理。
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()

从实验结果可以看出,相比均值

最低0.47元/天 解锁文章
707

被折叠的 条评论
为什么被折叠?



