1. 程式人生 > >OpenCV篇8---形態學轉換

OpenCV篇8---形態學轉換

學習目標:
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]]