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]]