1. 程式人生 > >【翻譯:OpenCV-Python教程】形態變化

【翻譯:OpenCV-Python教程】形態變化

⚠️這個系列是自己瞎翻的,文法很醜,主要靠意會,跳著跳著撿重要的部分翻,翻錯了不負責,就這樣哈。

⚠️基於3.4.3,Morphological Transformations,原文

目標

在這一章節,

理論

形態變換是基於影象形狀的一些簡單操作。 它通常在二進位制影象上執行。 它需要兩個輸入,一個是我們的原始影象,第二個是稱為結構元素或核心,它決定了操作的性質。 兩個基本的形態學運算子是侵蝕和膨脹。 然後它的變體形式如開放,閉合,梯度等等也發揮作用。 我們將在以下圖片的幫助下逐一看到它們:

j.png

 

1、侵蝕

侵蝕的基本思想就像土壤侵蝕一樣,它會侵蝕前景物體的邊界(總是試圖保持前景為白色)。它具體做了什麼? 核心在影象中滑動(如在上節提到的2D卷積中那樣)。只有當核心下的所有畫素都是1時,原始影象中的畫素(1或0)才會被認為是1,否則它會被侵蝕(變為零)。

所以那到底發生了啥,邊界附近的取決於核心大小的所有畫素都將被丟棄。 因此,前景物件的厚度或大小減小,或者影象中的白色區域減小。 它有助於消除小的白噪聲(正如我們在色彩空間章節中看到的那樣),分離兩個連線的物件等。

這裡,作為一個例子,我用一個完整的 5x5 核心。讓我們看看它是如何工作的:

import cv2 as cv

import numpy as np

img = cv.imread('j.png',0)

kernel = np.ones((5,5),np.uint8)

erosion = cv.erode(img,kernel,iterations = 1)

結果:

erosion.png

2、 膨脹

它剛好於侵蝕相反。這裡,如果核心下至少有一個畫素元素是 '1' ,那我們就認為這個畫素點為 '1' 。因此它令到影象上的白色區域或者前景的大小增加了。通常,在如去除噪聲這樣的情景下,侵蝕之後要用一次膨脹演算法。因為,侵蝕雖然能去掉白噪聲,但也會讓我們的物體縮小。因此我們要(用膨脹演算法把它再展開)。自從噪聲(從侵蝕演算法中)消失之後,它們就不會再(因為膨脹演算法而)出現了。但我們的物體區域會增加,它也有助於連線物體的破碎部分。

dilation = cv.dilate(img,kernel,iterations = 1)

結果:

dilation.png

3、開放

開放就是腐蝕之後接膨脹的另一種叫法。它有助於消除噪聲,就像我們在上面解釋的那樣,這裡我們使用 cv.morphologyEx() 方法。

opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)

結果:

opening.png

4、閉合

閉合與開放相反,膨脹之後接侵蝕。它有助於關閉掉前景物件上的小洞,或者物件上的小黑點。

closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)

結果:

closing.png

5、梯度

梯度是一張影象膨脹和侵蝕的差。

這個結果看起來像是物體的外邊線。

gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)

結果:

gradient.png

6、頂帽運算

它是原圖與執行過開放演算法的原圖之差,以下是示例是按一個9x9核心來進行的運算。

tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)

結果:

tophat.png

7、黑帽運算

它是原圖經過閉合運算之後的結果與原圖之差。

blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)

結果:

blackhat.png

結構化元素

在之前的示例中,我們在Numpy的幫助下手動建立了一個結構化的元素。它是長方形的,但在某些情況下,你可能需要圓形或者橢圓形的核心。所以為了達到這個目的,OpenCV 有個方法,cv.getStructuringElement() 。你只需要傳入核心的形狀以及大小,你就能得到你需要的核心。
 

# Rectangular Kernel
>>> cv.getStructuringElement(cv.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
>>> cv.getStructuringElement(cv.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
>>> cv.getStructuringElement(cv.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)

額外資源

練習


上篇:【翻譯:OpenCV-Python教程】影象平滑

下篇:【翻譯:OpenCV-Python教程】影象梯度