⚠️這個系列是自己瞎翻的,文法很醜,主要靠意會,跳着跳着撿重要的部分翻,翻錯了不負責,就這樣哈。
⚠️基於3.4.3,Morphological Transformations,附原文。
目標
在這一章節,
- 我們會學到不同的形態操作比如侵蝕,膨脹,開口,閉合等等。
- 我們會遇到不同的方法,好像:cv.erode(),cv.dilate(),cv.morphologyEx()等等。
理論
形態變換是基於圖像形狀的一些簡單操作。 它通常在二進制圖像上執行。 它需要兩個輸入,一個是我們的原始圖像,第二個是稱爲結構元素或內核,它決定了操作的性質。 兩個基本的形態學運算符是侵蝕和膨脹。 然後它的變體形式如開口,閉合,梯度等等也發揮作用。 我們將在以下圖片的幫助下逐一看到它們:
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)
結果:
image
2. Dilation
It is just opposite of erosion. Here, a pixel element is '1' if atleast one pixel under the kernel is '1'. So it increases the white region in the image or size of foreground object increases. Normally, in cases like noise removal, erosion is followed by dilation. Because, erosion removes white noises, but it also shrinks our object. So we dilate it. Since noise is gone, they won't come back, but our object area increases. It is also useful in joining broken parts of an object.
dilation = cv.dilate(img,kernel,iterations = 1)
Result:
image
3. Opening
Opening is just another name of erosion followed by dilation. It is useful in removing noise, as we explained above. Here we use the function, cv.morphologyEx()
opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
Result:
image
4. Closing
Closing is reverse of Opening, Dilation followed by Erosion. It is useful in closing small holes inside the foreground objects, or small black points on the object.
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
Result:
image
5. Morphological Gradient
It is the difference between dilation and erosion of an image.
The result will look like the outline of the object.
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)
Result:
image
6. Top Hat
It is the difference between input image and Opening of the image. Below example is done for a 9x9 kernel.
tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
Result:
image
7. Black Hat
It is the difference between the closing of the input image and input image.
blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
Result:
image
Structuring Element
We manually created a structuring elements in the previous examples with help of Numpy. It is rectangular shape. But in some cases, you may need elliptical/circular shaped kernels. So for this purpose, OpenCV has a function, cv.getStructuringElement(). You just pass the shape and size of the kernel, you get the desired kernel.
# 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)
Additional Resources
- Morphological Operations at HIPR2
Exercises
下篇:【翻譯:OpenCV-Python教程】