OpenCV 中的形態學轉換
阿新 • • 發佈:2019-01-03
1. 腐蝕(Erosion)
- 原理:卷積核沿著影象滑動,如果與卷積核對應的原影象的所有畫素值都是1,那麼中心元素就保持原來的畫素值,否則就變為零。
- 結果:對於
去除白噪聲
很有用,也可以用來斷開兩個連在一塊的物體等。
2. 膨脹(Dilation)
- 原理:與腐蝕相反,與卷積核對應的原影象的畫素值中只要有一個是1,中心元素的畫素值就是1 。
- 結果:會增加影象中的白色區域,也可以用來連線兩個分開的物體等。
3. 腐蝕和膨脹的程式碼及結果
img = cv2.imread('D:/j.jpg')
kernel = np.ones((6, 6), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1 )
dilation = cv2.dilate(erosion, kernel, iterations=1)
# 原圖
plt.subplot(131), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
# 腐蝕圖
plt.subplot(132), plt.imshow(erosion), plt.title('Eroded')
plt.xticks([]), plt.yticks([])
# 膨脹圖
plt.subplot(133), plt.imshow(dilation), plt.title('Dilated' )
plt.xticks([]), plt.yticks([])
plt.show()
4. 開運算
- 先腐蝕再膨脹
- 被用來去除噪聲
img = cv2.imread('D:/j_with_noise.jpg')
kernel = np.ones((6, 6), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
5. 閉運算
- 先膨脹再腐蝕
- 被用來填充前景物體中的小洞,或者前景物體上的小黑點
img = cv2.imread('D:/j_with_hole.jpg')
kernel = np.ones((6 , 6), np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
6. 形態學梯度
- 其實就是一幅影象
膨脹與腐蝕的差
,結果看上去就像前景物體的輪廓。
img = cv2.imread('D:/j.jpg')
kernel = np.ones((3, 3), np.uint8) # 注意卷積核大小的選取
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
7. 結構化元素的選取
在前面的例子中我們使用Numpy 構建了結構化元素
(kernel)
,它是正方形的。但有時我們需要構建一個橢圓形/圓形的核。為了實現這種要求,提供了OpenCV函式cv2.getStructuringElement()
。你只需要告訴他你需要的核的形狀和大小。
# Rectangular Kernel
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
array([[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]], dtype=uint8)
# Elliptical Kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
array([[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]], dtype=uint8)
# Cross-shaped Kernel
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
array([[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]], dtype=uint8)