opencv 影象形態學轉換
學習不同的形態學操作,例如腐蝕,膨脹,開運算,閉運算等
學習的函式有:cv2.erode(), cv2.dilate(), cv2.morphologyEx()等
原理
形態學操作是根據影象形狀進行的簡單操作,一般情況下對二值化影象進行的操作。需要輸入兩個引數,一個是原始影象,第二個被稱為結構化元素或核,它是用來決定操作的性質的。兩個基本的形態學操作是腐蝕和膨脹。他們的變體構成了開運算,閉運算,梯度等。
1、腐蝕
就像土壤侵蝕一樣,這個操作會把前景物體的邊界腐蝕掉,卷積核沿著影象滑動,如果與卷積核對應的原影象的所有畫素值都是 1,那麼中心元素就保持原來的畫素值,否則就變為零。根據卷積核的大小靠近前景的所有畫素都會被腐蝕掉(變為 0),所以前景物體會變小,這對於去除白噪聲很有用,也可以用來斷開兩個連在一塊的物體等。
這裡個例子,使用一個 5x5 的卷積核,其中所有的值都是1。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img, kernel,iterations=1)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(erosion),plt.title('erosion' )
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
2、 膨脹
與腐蝕相反,與卷積核對應的原影象的畫素值中只要有一個是 1,中心元素的畫素值就是 1。所以這個操作會增加影象中的白色區域(前景)。一般在去噪聲時先用腐蝕再用膨脹。因為腐蝕在去掉白噪聲的同時,也會使前景物件變小,所以再對其進行膨脹,這時噪聲已經被去除了,不會再回來了,但是前景還在並會增加。膨脹也可以用來連線兩個分開的物體。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png' )
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(img, kernel,iterations=1)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(dilation),plt.title('dilation')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
3 、開運算
先進行腐蝕再進行膨脹就叫做開運算,被用來去除噪聲。這裡我們用到的函式是 cv2.morphologyEx()。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
for i in range(2000):
temp_x = np.random.randint(0,img.shape[0])
temp_y = np.random.randint(0,img.shape[1])
img[temp_x][temp_y] = 255
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(opening),plt.title('opening')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
4、 閉運算
先膨脹再腐蝕。它經常被用來填充前景物體中的小洞,或者前景物體上的小黑點。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/3.png')
kernel = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(closing),plt.title('closing')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
5 、形態學梯度
其實就是一幅影象膨脹與腐蝕的差別,結果看上去就像前景物體的輪廓。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(gradient),plt.title('gradient')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
6、 禮帽
原始影象與進行開運算之後得到的影象的差。9*9核
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png')
kernel = np.ones((9,9),np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(tophat),plt.title('tophat')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
7 、黑帽
進行閉運算之後得到的影象與原始影象的差。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/2.png')
kernel = np.ones((9,9),np.uint8)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(blackhat),plt.title('blackhat')
plt.xticks([]),plt.yticks([])
plt.show()
結果圖:
8 、形態學操作之間的關係
我們把以上集中形態學操作之間的關係列出來以供大家參考
參考:OpenCV官方教程中文版(For Python)