翻译及二次校对:cvtutorials.com
目标
学习:
- 1. 用各种低通滤波器模糊图像
- 2. 在图像上应用定制的滤波器(二维卷积)
二维卷积 ( 图像滤波 )
与一维信号一样,图像也可以用各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF有助于去除噪音、模糊图像等。HPF滤波器有助于寻找图像的边缘。
OpenCV提供了一个函数cv.filter2D()来将一个核与图像进行融合。作为一个例子,我们将在一个图像上尝试一个平均滤波器。一个5x5的平均滤波核看起来就像下面这样。
这个操作是这样的:在一个像素上面保持这个核,把这个核下面的所有25个像素加起来,取平均值,然后用新的平均值替换中心像素。图像中的所有像素都施加这个操作。试试这段代码并检查结果。
代码语言:javascript复制import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('opencv_logo.png')
kernel = np.ones((5,5),np.float32)/25
dst = cv.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()
结果如下:
图像模糊(图像平滑)
图像模糊是通过用低通滤波器核对图像进行卷积实现的。它对去除噪音很有用。它实际上是从图像中去除高频内容(如:噪声、边缘)。因此,在这个操作中,边缘会被模糊一些(也有一些模糊技术是不模糊边缘的)。OpenCV提供了四种主要的模糊技术。
- 1. 均值模糊
这是通过用一个归一化的盒式滤波器对图像进行卷积来完成的。它只是取核区下所有像素的平均值,并替换中心元素。这是由函数cv.blur()或cv.boxFilter()完成的。查看文档以了解关于核的更多细节。我们应该指定核的宽度和高度。一个3x3的归一化盒式滤波器看起来就像下面这样。
注意:如果你不想使用规范化的盒子过滤器,请使用cv.boxFilter()。向该函数传递一个参数normalize=False。
请看下面的样本演示,核大小为5x5。
代码语言:javascript复制import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('opencv-logo-white.png')
blur = cv.blur(img,(5,5))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()
结果如下:
- 1. 高斯模糊
在这个方法中,使用了高斯核而不是盒式滤波器。它是通过函数cv.GaussianBlur()完成的。我们应该指定核的宽度和高度,应该是正数和奇数。我们还应该指定X和Y方向的标准偏差,分别为sigmaX和sigmaY。如果只指定sigmaX,sigmaY将被视为与sigmaX相同。如果两者都是零,则根据核大小计算。高斯模糊对去除图像中的高斯噪声非常有效。
如果你愿意,你可以用函数cv.getGaussianKernel()创建一个高斯核。
上面的代码可以为高斯模糊进行修改。
代码语言:javascript复制blur = cv.GaussianBlur(img,(5,5),0)
结果如下:
- 1. 中值模糊
在这里,函数cv.medianBlur()取核区下所有像素的中值,中心元素被替换成这个中值。这对图像中的椒盐噪声非常有效。有趣的是,在上述过滤器中,中心元素是一个新的计算值,可能是图像中的一个像素值或一个新值。但在中值模糊中,中心元素总是被图像中的某个像素值所取代。它能有效地减少噪音。它的核大小应该是一个正奇数的整数。
在这个演示中,我给我们的原始图像添加了50%的噪声,并应用中值模糊。检查一下结果。
代码语言:javascript复制median = cv.medianBlur(img,5)
结果:
- 1. 双边滤波
cv.bilateralFilter()在去除噪声的同时保持边缘的清晰度方面非常有效。但与其他过滤器相比,其操作速度较慢。我们已经看到,高斯滤波器取像素周围的邻域并找到其高斯加权平均值。这个高斯滤波器是一个单独的空间函数,也就是说,在过滤时考虑附近的像素。它不考虑像素是否有几乎相同的灰度。它不考虑一个像素是否是一个边缘像素。因此,它也模糊了边缘,这是我们不希望看到的。
双边滤波也需要一个空间的高斯滤波,但多了一个高斯滤波,这是一个像素差异的函数。空间的高斯函数确保只有附近的像素被考虑用于模糊处理,而灰度差的高斯函数则确保只有那些与中心像素灰度相似的像素被考虑用于模糊处理。所以它保留了边缘,因为边缘的像素会有很大的灰度变化。
下面的例子显示了双边滤波器的使用(关于参数的细节,请访问文档)。
代码语言:javascript复制blur = cv.bilateralFilter(img,9,75,75)
结果:
看,表面的纹理已经消失了,但边缘仍然保存着。