空间滤波是一种图像处理技术,它通过对每个像素周围的像素进行加权平均来平滑图像。这个过程的基本思想是,将每个像素的灰度值与它周围像素的灰度值进行加权平均,然后用平均值来替换原来的像素值。空间滤波器的大小和形状决定了每个像素的加权因子,这些因子决定了每个像素对最终结果的贡献程度。通常使用矩形或方形的空间滤波器,但也可以使用其他形状的滤波器,如圆形或椭圆形。
空间滤波可以用来去除图像中的噪点或平滑图像,但是它也会模糊图像的细节。因此,在使用空间滤波时,必须权衡滤波器的大小和形状以及要达到的效果之间的平衡。
空间滤波的机理
空间滤波的机理就是在待处理图像上逐像素地移动模板,在每个像素点,滤波器的响应通过事先定义的关系计算。若滤波器在图像像素上执行的是线性操作,则称为线性滤波器,否则为非线性滤波器。
均值滤波器求解的是模板内像素灰度值的平均值,是典型的线性滤波器。统计排序滤波器是通过给定邻域内的灰度值大小实现的,原始数据与滤波结果是一种逻辑关系。
对于一幅m*n的模板,假设m=2*a+1,n=2*b+1,a,b均为正整数,使用m*n大小的模板K对M*N大小的图像S进行线性空间滤波,得到T图像。
其中(x,y)表示图像某一像素点。
假设我们有一幅图像,其中一个像素的灰度值为 200,它周围的四个像素的灰度值分别为 100、150、180 和 220。如果我们使用大小为 3x3 的方形空间滤波器来平滑这幅图像,那么我们会将每个像素的灰度值与它周围像素的灰度值进行加权平均,然后用平均值来替换原来的像素值。在这种情况下,每个像素的加权因子都是相同的,因此我们将所有像素的灰度值除以周围像素的数量(也就是 4),得到的平均值就是新的像素值。在这种情况下,中心像素的新灰度值为(100+150+180+220+200)/ 5=178。
空间滤波器的大小和形状可以改变加权因子的计算方式,例如,我们可以使用更大的滤波器来平滑图像,或者使用更复杂的形状来保留更多的细节。
实现空间滤波邻域处理时,需要考虑的一个问题是滤波中心靠近图像边界时如何计算空间滤波器的响应。
当滤波器的中心靠近图像边界时,可以使用边界处理来计算空间滤波器的响应。 边界处理可以帮助您在图像的边界处正确处理滤波器,使滤波器能够正常工作。
具体来说,可以采用以下几种方法之一来处理边界:
填充:在图像的边界外增加一圈像素,并使用某些方法(例如反射、循环、常量填充等)填充这些像素。 这样,就可以在边界外使用滤波器,而无需担心边界问题。
截断:在滤波器的中心超出图像边界的情况下,将滤波器的大小截断为与图像大小相同。 这样,就可以在图像内使用滤波器,而无需担心边界问题。
边界复制:将图像的边界像素复制到图像的外部,以便滤波器可以在边界外使用。 这种方法通常不太常用,因为它可能会导致边界处的伪影。
哪种方法最好取决于应用场景和需求。 通常来说,填充和截断是比较常用的边界处理方法。
考虑一个大小为m*n的一个模板,当模板中心距离左边界或右边界为(n-1)/2个图像时,该模板一条边与图像左或右边界重合;当模板中心距离上边界或下边界为(m-1)/2个图像时,该模板一条边与图像上或下边界重合,如果继续向边界靠近,那么模板的行或者列就会处于图像平面之外。较为简单的方法就是将中心点限制不让模板出图像以外。这种解决方法处理后图像比原始图像小,可以将未被处理的灰度值直接复制到滤波结果处,保持滤波结果和原图像一致。另一种是在图像左右边界补上灰度为(n-1)/2,上下边界补上灰度为(m-1)/2灰度为0的像素点,再进行滤波处理。
import numpy as np
def corre12d(img, window):
m = window.shape[0]
n = window.shape[1]
# 边界通过0灰度值填充
img1 = np.zeros((img.shape[0] + m - 1, img.shape[1] + n - 1))
img1[(m - 1) // 2:(img.shape[0] + (m - 1) // 2), (n - 1) // 2:(img.shape[1] + (n - 1) // 2)] = img
img2 = np.zeros(img.shape)
for i in range(img2.shape[0]):
for j in range(img2.shape[1]):
tmp = img1[i:i + m, j:j + n]
img2[i, j] = np.sum(np.multiply(tmp, window))
return (img1, img2)
# window表示滤波模板 img原始矩阵
window = np.array([[1, 0, 0], [0, 0, 0], [0, 0, 2]])
img = np.array(np.array([[1, 2, 1, 0, 2, 3], [0, 1, 1, 2, 0, 1],
[3, 0, 2, 1, 2, 2], [0, 1, 1, 0, 0, 1],
[1, 1, 3, 2, 2, 0], [0, 0, 1, 0, 1, 0]]))
# img1表示边界填充后矩阵,img2表示空间滤波结果
img1, img2 = corre12d(img, window)
print(img1)
print()
print(img2)
控制台:
[[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 2. 1. 0. 2. 3. 0.]
[0. 0. 1. 1. 2. 0. 1. 0.]
[0. 3. 0. 2. 1. 2. 2. 0.]
[0. 0. 1. 1. 0. 0. 1. 0.]
[0. 1. 1. 3. 2. 2. 0. 0.]
[0. 0. 0. 1. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]]
[[2. 2. 4. 0. 2. 0.]
[0. 5. 4. 5. 4. 2.]
[2. 2. 1. 1. 4. 0.]
[2. 9. 4. 6. 1. 2.]
[0. 2. 1. 3. 0. 0.]
[0. 1. 1. 3. 2. 2.]]
空间滤波器模板
空间滤波器是一种在图像处理中常用的工具,它可以对图像进行平滑、锐化、边缘检测等操作。滤波器的模板是指用于滤波的系数矩阵,其中的每个元素都有特定的意义。常用的空间滤波器模板有以下几种:
均值滤波器:模板中的所有元素都相等,常用于图像平滑。
高斯滤波器:模板中的元素满足高斯分布,常用于图像平滑。
中值滤波器:模板中的所有元素都相等,但是元素的值是图像中某一点的像素值的中值,常用于去除图像中的椒盐噪声。
Sobel滤波器:模板中的元素为一个3x3的系数矩阵,常用于图像边缘检测。
Prewitt滤波器:模板中的元素为一个3x3的系数矩阵,常用于图像边缘检测。
Laplacian滤波器:模板中的元素为一个3x3的系数矩阵,常用于图像边缘检测。
Canny滤波器:模板中的元素为一个5x5的系数矩阵,常用于图像边缘检测。
若空间滤波器模板系数从1开始进行索引,从左向右索引值递增,先索引第一行每个模板系数,再依次索引下一行每个模板系数。w向量表示滤波模板,z向量表示模板覆盖像素灰度值,3*3滤波模板响应R表示为:
例:3*3滤波模板
空间滤波器是指在图像空间中进行卷积运算的滤波器,它是图像处理中常用的工具之一。通常,空间滤波器是用一个模板来进行卷积运算的,模板就是一个矩阵,称为卷积核(或者称为滤波器核)。
模板的大小和形状通常是固定的,常用的模板大小包括3x3、5x5、7x7等,形状包括圆形、方形、长条等。模板中的数值可以是实数或者整数,由于卷积运算是基于图像的像素进行计算的,所以模板中的数值通常与图像的像素值有关。
空间滤波器的模板可以是手动设计的,也可以是使用特定算法自动生成的。在实际应用中,使用现成的模板是一种比较常见的做法,这样可以节省设计时间,同时也可以保证模板的质量。常用的模板包括高斯模板、均值模板、中值模板、Sobel模板等。
这里我们使用skimage库:
使用skimage中的空间滤波器模板,需要先导入skimage库和skimage.filters模块。然后,可以使用skimage.filters模块中的相应函数来调用模板。
from matplotlib import pyplot as plt
from skimage import io ,filters,util
# 读入待处理的图像
image = io.imread('Test_Gray.jpg')
#加噪
noise=util.random_noise(image,mode='s&p',amount=0.1)
# 使用高斯模板进行空间滤波
filtered_image = filters.gaussian(image)
plt.subplot(121)
plt.title("noise")
plt.imshow(noise,cmap='gray')
plt.subplot(122)
plt.title("filtered_image")
plt.imshow(filtered_image,cmap='gray')
plt.show()
除了高斯模板,skimage还提供了许多其他的空间滤波器模板,包括均值模板、中值模板、Sobel模板等。使用方法都类似,只需要替换相应的函数即可。
你也可以使用matplotlib库中的imshow函数显示自定义图像滤波模板
import scipy.signal
import matplotlib.pyplot as plt
import numpy as np
from skimage import io
# 读入待处理的图像
image = io.imread("Test_Gray.jpg")
# 自定义滤波模板
template = np.ones((20, 20)) / (20 ** 2)
# 使用自定义滤波模板进行卷积运算
filtered_image = scipy.signal.convolve(image, template, mode='same')
# 使用matplotlib.pyplot.imshow函数显示结果图像
plt.subplot(121)
plt.title("Original")
plt.imshow(image, cmap='gray')
plt.subplot(122)
plt.title("filtered_image")
plt.imshow(filtered_image, cmap='gray')
plt.show()
template变量是自定义的滤波模板,是一个3x3的矩阵。mode参数指定了卷积运算的模式,这里使用了'same'模式,表示输出图像的尺寸和输入图像的尺寸相同。
然后使用matplotlib.pyplot.imshow函数显示结果图像,cmap参数指定了使用的色彩映射类型,这里使用了灰度色彩映射