OpenCV(Python3)_13(形态学变换)

目标

在这一章当中

理论

形态学变换是基于图像形状所进行一些简单操作。它通常是在二值化图像上进行处理。它需要两个输入,一个是我们的原始图像,另一个是决定操作性质的结构元素内核两个基本的形态学算子是腐蚀和膨胀。然后它的变体构成了开运算,闭运算,梯度等。我们会以下图为例进行逐一的介绍。

j.png
图片

1.侵蚀

腐蚀的基本思想就像土壤腐蚀一样,它腐蚀了前景物体的边界(前景一般为白色)。那么它是怎么做到的呢?内核在图像中滑动(如2D卷积)。如果与卷积所对应的原图像的所有像素值都是1,那么中心元素就保持着原来的像素值,否则就变为零。

那么这会产生什么影响呢。根据卷积核的大小,靠近前景附近的所有像素都将被丢弃。因此,前景物体的厚度或大小会减小,或者图像中的白色区域会减少。这对于消除小的白噪声是有用的(正如我们在彩色空间章节看到的那样),同时也可以用来分离两个连接的物体等等。

在这里,作为一个例子,我将使用一个5x5的内核。让我们看看它是如何工作的:

程序:

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel,iterations = 1)
#image,kernel,number of times erosion is applied.

cv.imshow('src',erosion)
cv.waitKey(0)

结果:

                                                                                

2.膨胀

这与腐蚀正好相反。这里,如果与内核相对应的图像至少一个像素是'1',那么中心元素的像素值就是'1'。所以它增加了图像中的白色区域或增加了前景物体的大小。通常情况下,在噪音消除的情况下,腐蚀会伴随着扩张。因为腐蚀会消除白色噪音,但它也会缩小我们的目标。所以我们膨胀它。由于噪音消失了,他们不会回来,但我们的物体面积增加了。它在连接对象的分开部分时也很有用。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
dilation = cv.dilate(img,kernel,iterations = 1)
#image,kernel,number of times erosion is applied.

cv.imshow('src',dilation)
cv.waitKey(0)

结果:

                                                                                  

3.开运算

开运算是先进行腐蚀,然后在进行膨胀。正如我们上面所解释的那样,它在消除噪音方面很有用 这里我们使用函数cv.morphologyEx()。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('opening.png',0)
kernel = np.ones((5,5),np.uint8)
opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
#image,kernel,number of times erosion is applied.

cv.imshow('src',img)
cv.imshow('fin',opening)

cv.waitKey(0)

结果:

                                       

4.闭运算

与开运算相反,闭运算是先进行膨胀,然后再进行腐蚀这对于消除前景物体内的小孔或物体上的小黑点很有用。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('closing.png',0)
kernel = np.ones((5,5),np.uint8)
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
#image,kernel,number of times erosion is applied.

cv.imshow('src',img)
cv.imshow('fin',closing)
cv.waitKey(0)

结果:

                                       

5.形态梯度

就是图像膨胀和腐蚀的查。结果将看起来像前景对象的轮廓。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)
#image,kernel,number of times erosion is applied.

cv.imshow('src',img)
cv.imshow('fin',gradient)
cv.waitKey(0)

结果:

                                                             

6.高顶

这是输入图像和图像经开运算后的查。下面的例子是为9x9内核完成的。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((9,9),np.uint8)
opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
#image,kernel,number of times erosion is applied.

cv.imshow('src',img)
cv.imshow('open',opening)
cv.imshow('fin',tophat)

cv.waitKey(0)

结果:

                                    

7.黑帽

这是输入图像和输入图像经闭运算的差。

程序:

import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((9,9),np.uint8)
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
#image,kernel,number of times erosion is applied.

cv.imshow('src',img)
cv.imshow('open',closing)
cv.imshow('fin',blackhat)

cv.waitKey(0)

结果:

                                          

结构元素

在Numpy的帮助下,我们在前面的例子中手动创建了一个结构元素。它是矩形的。但在某些情况下,您可能需要椭圆形/圆形的内核。所以为此,OpenCV有一个函数cv.getStructuringElement()您只需传递内核的形状和大小,即可获得所需的内核。

程序:

import cv2 as cv
import numpy as np

# Rectangular Kernel
print(cv.getStructuringElement(cv.MORPH_RECT,(5,5)))
print(" ")
# Elliptical Kernel
print(cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)))
print(" ")
# Cross-shaped Kernel

print(cv.getStructuringElement(cv.MORPH_CROSS,(5,5)))

结果:

               

猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80763479