OpenCV篇8---形态学转换

学习目标:
1、学习不同的形态操作,如腐蚀,膨胀,开放,闭幕等;

2、学习这些函数,如:cv2.erode(),cv2.dilate(),cv2.morphologyEx()等;

原理

形态转换是基于图像形状的一些简单操作,它通常在二进制图像上执行。它需要两个输入,一个是我们的原始图像,另一个是决定操作性质的结构元素或内核。 两个基本的形态学算子是侵蚀和膨胀,然后它的变体形式有开运算,闭运算,渐变等。 我们将在以下图像的帮助下逐一看到它们:

原始图像:


1、腐蚀

腐蚀的基本思想就像土壤侵蚀,它腐蚀了前景物体的边界(总是试图保持前景为白色)。内核在图像中滑动(如2D卷积),原始图像(1或0)中的像素仅在内核下的所有像素为1时才被视为1,否则会被腐蚀(设为0)。

那么发生什么呢?边界附近的所有像素都将被丢弃,这取决于内核的大小。 因此,前景物体的厚度或大小会减小,或者图像中的白色区域会减少。 这对于消除小的白噪声或分离两个连接的物体是有用的。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/j.png', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


2、膨胀

这与腐蚀正好相反。这里,如果内核下的至少一个像素是'1',则像素元素是'1'。所以它增加了图像中的白色区域或增加了前景物体的大小。通常情况下,在噪音消除的情况下,腐蚀会伴随着膨胀。因为腐蚀会消除白色噪音,但它也会缩小我们的目标。所以需要将它膨胀。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/j.png', 0)
kernel = np.ones((5, 5), np.uint8)
dilation = cv2.dilate(img,kernel,iterations = 1)
cv2.imshow('dilation', dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


3、开运算

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

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/opening.png', 0)
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('original', img)
cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


4、闭运算

闭运算是先膨胀后腐蚀的一种操作。 它对于关闭前景物体内的小孔或物体上的小黑点很有用。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/closing.png', 0)
kernel = np.ones((5, 5), np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('original', img)
cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


5、形态梯度

形态梯度区别于图像膨胀和侵蚀,结果将看起来像是对象的轮廓。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/j.png', 0)
kernel = np.ones((5, 5), np.uint8)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('original', img)
cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


6、礼帽

原图像与其进行开运算后的图像进行一个差,适用于去除图像外噪声。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/j.png', 0)
kernel = np.ones((9, 9), np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('original', img)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


7、黑帽

原图像与其进行闭运算后的图像进行一个差,适用于去除图像内噪声。

范例:

#coding:utf8
import cv2
import numpy as np
img = cv2.imread('F:/j.png', 0)
kernel = np.ones((9, 9), np.uint8)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('original', img)
cv2.imshow('blackhat', blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:


结构元素:

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

范例:

#coding:utf8
import cv2
# Rectangular Kernel
Array1 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
print ("Array1:", Array1)

# Elliptical Kernel
Array2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
print ("Array2:", Array2)

# Cross-shaped Kernel
Array3 = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
print ("Array3:", Array3)

输出:

Array1: [[1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]]
Array2: [[0 0 1 0 0]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [0 0 1 0 0]]
Array3: [[0 0 1 0 0]
 [0 0 1 0 0]
 [1 1 1 1 1]
 [0 0 1 0 0]
 [0 0 1 0 0]]

猜你喜欢

转载自blog.csdn.net/songchunxiao1991/article/details/80234350