形態學操作是根據圖像形狀進行的簡單操作。一般情況下對二值化圖像進行的操作。
膨脹:減少亮區; 腐蝕:擴大亮區
結構化元素
構建核的形狀和大小方法:cv2.getStructuringElement()
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)
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)
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)
腐蝕
這個操作會把前景物體的邊界腐蝕掉(但是前景仍然是白色)。
實現原理:卷積核B沿着圖像A滑動,並將B所對應的最小值賦值給A像素中心點。
對於二值圖像,如果與卷積核對應的原圖像的所有像素值都是 1,那么中心元素就保持原來的像素值,否則就變為零。
代碼:
1 import numpy as np 2 import cv2 3 from matplotlib import pyplot as plt 4
5 # 灰度模式讀取圖像
6 img = cv2.imread("../image/girl.jpg", cv2.IMREAD_GRAYSCALE) 7
8 # 生成深度為8的卷積核
9 kernel = np.ones((5, 5), np.uint8) 10
11 # iterations表示迭代的次數
12 erosion = cv2.erode(img, kernel, iterations=1) 13
14 plt.subplot(121), plt.imshow(img, cmap="gray"), plt.title("Original") 15 plt.subplot(122), plt.imshow(erosion, cmap="gray"), plt.title("Erosion") 16 plt.show()
結果:
一般灰度圖 轉成二值圖像:

膨脹
實現原理:卷積核B沿着圖像A滑動,並將B所對應的最大值賦值給A像素中心點。
對於二值圖像,如果與卷積核對應的原圖像只要有一個像素值是 1,那么中心元素就為1。
代碼:
1 dilation = cv2.dilate(img, kernel, iterations=1)
結果:
一般灰度圖: 轉換成二值圖像:

開運算
對圖像進行先腐蝕再膨脹,主要用來出去圖像中的白噪聲,也可以將圖像中兩個粘在一起的物體分開。
函數是 cv2.morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
代碼:
1 import numpy as np 2 import cv2 3 from matplotlib import pyplot as plt 4
5 # 灰度模式讀取圖像
6 img = cv2.imread("../image/erosion.jpg", cv2.IMREAD_GRAYSCALE) 7 # ret, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
8
9 # 生成深度為8的卷積核
10 kernel = np.ones((5, 5), np.uint8) 11
12 # cv2.MORPH_OPEN表示開運算
13 opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 14
15 plt.subplot(121), plt.imshow(img, cmap="gray"), plt.title("Original") 16 plt.subplot(122), plt.imshow(opening, cmap="gray"), plt.title("Opening") 17 plt.show()
結果:

閉運算
先膨脹再腐蝕。它經常被用來填充前景物體中的小洞,或者前景物體上的小黑點。
代碼:
# cv2.MORPH_CLOSE表示閉運算 close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
結果:

形態學梯度
它是膨脹與腐蝕的差,該操作能描述圖像亮度變化的劇烈程度。當我們想突出高亮區域的外圍時,通常可以使用形態學梯度,因為從原區域的膨脹中減去了原區域的收縮,所以留下了圖像的外圍邊緣
代碼:
# cv2.MORPH_GRADIENT 表示形態學梯度 gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
結果:

禮貌、黑帽
禮貌操作時原始圖像與進行開運算后的圖像的差。
黑帽操作是進行閉運算得到的圖像與原始圖像的差
開運算帶來的結果是放大裂縫或局部低亮度區域,因此A - Open(A)可以突出比A周圍的區域更明亮的區域,並跟核的大小相關;相反,黑帽操作則能突出比A的周圍區域黑暗的區域
代碼:
# cv2.MORPH_TOPHAT 表示禮貌操作 tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) # cv2.MORPH_BLACKHAT 表示黑帽 # gradient = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
結果:
禮貌: 黑帽:

