python-opencv Tutorials 一码人翻译(13)图像处理— 平滑图像

目标

学习:

用各种低通滤波器模糊图像

将定制的过滤器应用于图像(2D卷积)

  • 2D卷积(图像滤波)

   在一维信号中,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等来过滤,LPF有助于消除噪声,模糊图像等。HPF过滤器有助于在图像中寻找边缘。

   OpenCV提供了一个函数cv.filter2D()来将一个内核与一个图像进行卷积。作为一个例子,我们将在一个图像上尝试一个平均滤波器。一个5x5的平均过滤内核如下所示:

   操作是这样的:将这个内核保持在一个像素之上,将所有25个像素添加到这个内核下面,取其平均值,用新的平均值替换中心像素。它将继续这个操作,以获取图像中的所有像素。尝试这段代码并检查结果:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('glenna.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()。传递一个参数,使函数的值为False。在下面的示例演示中,使用一个5x5大小的内核:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('glenna.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()

  • 2。高斯模糊

在这个过程中,使用的是高斯内核,而不是box过滤器。它是由函数cv.GaussianBlur()完成的。我们应该指定内核的宽度和高度,应该是正的和奇数的。我们还应该分别指定X和Y方向上的标准差,sigmaX和sigmaY。如果只指定sigmaX,sigmaY就与sigmaX相同。如果两者都是0,那么它们是从内核大小来计算的。高斯模糊在从图像中去除高斯噪声是非常有效的。

如果您想要,您可以创建一个带有函数的高斯内核,cv.getGaussianKernel()。

上面的代码可以被修改为高斯模糊:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('glenna.png')

blur = cv.GaussianBlur(img,(5,5),0)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('GaussianBlur')
plt.xticks([]), plt.yticks([])
plt.show()

  • 3。模糊中值

在这里,函数cv.medianBlur()接受内核区域内所有像素的中值,中间元素被替换为中值。这对图像中盐和胡椒的噪音是非常有效的。有趣的是,在上面的过滤器中,中心元素是一个新计算的值,它可能是图像中的一个像素值或一个新的值。但在中值模糊中,中心元素总是被图像中的某个像素值所取代。它有效地减少了噪音。它的内核大小应该是一个正奇数。

在这个演示中,我给原来的图像添加了50%的噪声和应用中值模糊。检查结果:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('nlenna.jpg')

median = cv.medianBlur(img,5)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(median ),plt.title('medianBlur')
plt.xticks([]), plt.yticks([])
plt.show()

  • 4  双边滤波

双侧向过滤()在消除噪声方面非常有效,同时保持边缘锐利。但与其他过滤器相比,操作速度较慢。我们已经看到高斯滤波器在像素周围移动了一个区域并找到它的高斯加权平均值。这个高斯滤波器是一个空间的函数,也就是说,在过滤时考虑附近的像素。它不考虑像素是否有几乎相同的强度。它不考虑像素是否是一个边缘像素。所以它模糊了边缘,我们也不想这样做。

双边滤波器在空间中也采用高斯滤波器,但另一种高斯滤波器是像素差的函数。空间的高斯函数确保只有附近的像素被认为是模糊的,而强度差的高斯函数只确保那些与中心像素相似的像素被认为是模糊的。所以它保留了边缘,因为边缘的像素会有很大的强度变化。

下面的示例展示了使用双边过滤器(关于参数的详细信息,访问文档)。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('nlenna.jpg')

blur = cv.bilateralFilter(img,9,75,75)

plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur ),plt.title('bilateralFilter')
plt.xticks([]), plt.yticks([])
plt.show()

猜你喜欢

转载自blog.csdn.net/qq_41905045/article/details/81334443