Python-OpenCV中的圖像處理-形態學轉換
- 形態學轉換
- 腐蝕
- 膨脹
- 開運算
- 閉運算
- 形態學梯度
- 禮帽
- 黑帽
- 形態學操作之間的關系
- 形態學代碼例程
形態學轉換
- 形態學操作:腐蝕,膨脹,開運算,閉運算,形態學梯度,禮帽,黑帽等
- 主要涉及函數:cv2.erode(), cv2.dilate(), cv2.morphologyEx()
- 原理:形態學操作是根據圖像形狀進行的簡單操作。一般情況下對二值化圖像進行的操作。需要輸入兩個參數,一個是原始圖像,第二個被稱為結構化元素或核,它是用來決定操作的性質的。兩個基本的形態學操作是腐蝕和膨脹。他們的變體構成了開運算,閉運算,梯度等。
腐蝕
就像土壤侵蝕一樣,這個操作會把前景物體的邊界腐蝕掉(但是前景仍然是白色)。這是怎么做到的呢?卷積核沿著圖像滑動,如果與卷積核對應的原圖像的所有像素值都是 1,那么中心元素就保持原來的像素值,否則就變為零。這回產生什么影響呢?根據卷積核的大小靠近前景的所有像素都會被腐蝕掉(變為 0),所以前景物體會變小,整幅圖像的白色區域會減少。這對于去除白噪聲很有用,也可以用來斷開兩個連在一塊的物體等。
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((5,5), np.uint8)
erosion = cv2.erode(img, kernel=kernel, iterations=1)plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(erosion, cv2.COLOR_BGR2RGB)), plt.title('erode'), plt.xticks([]), plt.yticks([])
plt.show()
膨脹
與腐蝕相反,與卷積核對應的原圖像的像素值中只要有一個是 1,中心元素的像素值就是 1。所以這個操作會增加圖像中的白色區域(前景)。一般在去噪聲時先用腐蝕再用膨脹。因為腐蝕在去掉白噪聲的同時,也會使前景對象變小。所以我們再對他進行膨脹。這時噪聲已經被去除了,不會再回來了,但是前景還在并會增加。膨脹也可以用來連接兩個分開的物體。
import numpy as np
import cv2
from matplotlib import pyplot as plt# 膨脹
img = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Original_Image.png', cv2.IMREAD_GRAYSCALE)kernel = np.ones((5,5), np.uint8)
dilation = cv2.dilate(img, kernel=kernel, iterations=1)plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(dilation, cv2.COLOR_BGR2RGB)), plt.title('dilate'), plt.xticks([]), plt.yticks([])
plt.show()
開運算
先腐蝕再膨脹就叫做開運算。它被用來去除噪聲。這里我們用到的函數是 cv2.morphologyEx()
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
閉運算
先膨脹再腐蝕就叫做閉運算。它經常被用來填充前景物體中的小洞,或者前景物體上的小黑點
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
形態學梯度
其實就是一幅圖像膨脹與腐蝕的差別,結果看上去就像前景物體的輪廓。
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
禮帽
原始圖像與進行開運算之后得到的圖像的差。下面的例子是用一個 9x9 的核進行禮帽操作的結果。
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽
進行閉運算之后得到的圖像與原始圖像的差
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
形態學操作之間的關系
形態學轉換
- Opening:
dst = open(src, element) = dilate(erode(src, element), element) - Closing:
dst = close(src, element) = erode(dilate(src, element), element) - Morphological gradient:
dst = morph_grad(src, element) = dilate(src, element) - erode(src, element) - “Top hat”:
dst = tophat(src, element) = src - open(src, element) - “Black hat”:
dst = blackhat(src, element) = close(src, element) - src
形態學代碼例程
import numpy as np
import cv2
from matplotlib import pyplot as plt'''
形態學轉換
Opening: dst = open(src, element) = dilate(erode(src, element), element)Closing:dst = close(src, element) = erode(dilate(src, element), element)Morphological gradient:dst = morph_grad(src, element) = dilate(src, element) - erode(src, element)"Top hat":dst = tophat(src, element) = src - open(src, element)"Black hat":dst = blackhat(src, element) = close(src, element) - src
'''# 開運算
# 先進行腐蝕在進行膨脹叫做開運算。用來去除噪音
# opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)# 閉運算
# 先進行膨脹再進行腐蝕叫做閉運算。用來填充前景物體中的小洞,或者全景上的小黑點。
# closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)# 形態學梯度
# 就是一副圖像膨脹與腐蝕的差別,結果看上去就像前景物體的輪廓。
# gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)# 禮帽
# 原始圖像與進行開運算之后得到的圖像的差
# tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)# 黑帽
# 原始圖像與進行閉運算之后得到的圖像的差
# blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)# 結構化元素
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) # 矩形核
kernel_elli = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)) # 橢圓核
kernel_cros = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5)) # 十字核# 卷積核
# kernel = kernel_rects
# kernel = kernel_elli
# kernel = kernel_cros
kernel = np.ones((5,5), np.uint8)
kernel9x9 = np.ones((15,15), np.uint8)img_origin = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_COLOR)
img_gray = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_GRAYSCALE)# 開運算 腐蝕=>膨脹
opening = cv2.morphologyEx(img_gray, cv2.MORPH_OPEN, kernel)# 閉運算 膨脹=>腐蝕
closing = cv2.morphologyEx(img_gray, cv2.MORPH_CLOSE, kernel)# 梯度 膨脹-腐蝕
gradient = cv2.morphologyEx(img_gray, cv2.MORPH_GRADIENT, kernel)# 禮帽 原始圖像與進行開運算之后得到的圖像的差
tophat = cv2.morphologyEx(img_gray, cv2.MORPH_TOPHAT, kernel9x9)# 黑帽 進行閉運算之后與原始圖像的圖像的差
blackhat = cv2.morphologyEx(img_gray, cv2.MORPH_BLACKHAT, kernel9x9)# 腐蝕
erosion = cv2.erode(img_gray, kernel=kernel, iterations=1)# 膨脹
dilation = cv2.dilate(img_gray, kernel=kernel, iterations=1)plt.subplot(331), plt.imshow(cv2.cvtColor(img_origin,cv2.COLOR_BGR2RGB), 'gray'), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(332), plt.imshow(img_gray, 'gray'), plt.title('gray'), plt.xticks([]), plt.yticks([])
plt.subplot(333), plt.imshow(opening, 'gray'), plt.title('open'), plt.xticks([]), plt.yticks([])
plt.subplot(334), plt.imshow(closing, 'gray'), plt.title('close'), plt.xticks([]), plt.yticks([])
plt.subplot(335), plt.imshow(gradient, 'gray'), plt.title('gradient'), plt.xticks([]), plt.yticks([])
plt.subplot(336), plt.imshow(tophat, 'gray'), plt.title('tophat'), plt.xticks([]), plt.yticks([])
plt.subplot(337), plt.imshow(blackhat, 'gray'), plt.title('blackhat'), plt.xticks([]), plt.yticks([])
plt.subplot(338), plt.imshow(erosion, 'gray'), plt.title('erode'), plt.xticks([]), plt.yticks([])
plt.subplot(339), plt.imshow(dilation, 'gray'), plt.title('dilate'), plt.xticks([]), plt.yticks([])
plt.show()