OpenCV 擴張

Salman Mehmood 2024年2月15日
OpenCV 擴張

本文將解釋像侵蝕和擴張這樣的形態變換概念,我們使用它們在 OpenCV 中的影象中從給定物件的邊界新增和刪除畫素。

在 OpenCV 中使用侵蝕和擴張對影象應用形態變換

形態變換是在二值影象上執行的基於影象的操作。它需要兩個輸入,一個是原始影象,第二個是核心。

核心決定操作的性質。兩個基本的形態學運算元是侵蝕和擴張,我們也有它的一些變體,例如開閉等。

讓我們通過一個例子來理解侵蝕和擴張。

侵蝕和擴張

侵蝕就像土壤侵蝕一樣;它侵蝕了前景物體的邊界。考慮這張 L 的影象,其中白色部分是數字 1,從 OpenCV 標準的角度來看,它也可以視為數字 255。

侵蝕會移除給定影象中物件邊界處的畫素。在影象中移除該物件 L 的邊界後,在應用侵蝕後它會變薄。

從技術上講,核心在影象中滑動,就像在 2D 卷積中一樣。原始影象中的一個畫素,無論是 1 還是 0,只有在核心下的所有畫素都為 1 時才會被認為是 1;否則,它會被侵蝕或歸零,因此根據核心的大小丟棄邊界。

擴張與侵蝕相反;它將畫素新增到給定影象中物件的邊界。我們可以看到影象中 L 或物體 L 的邊界在膨脹後變得更厚。

從技術上講,如果核心下至少有一個畫素為 1,則一個畫素元素為 1,其結果將增加影象中的白色區域或前景物件的大小。

因此,如果你有一張想要去除噪聲的影象,你可以先應用侵蝕操作,然後再進行膨脹,因為侵蝕會去除白噪聲,但也會縮小我們的物件;這就是我們進行膨脹的原因,從而保留原始影象。它也可用於連線物件的破損部分。

侵蝕和擴張變化

形態變換有開、關等變化;開啟是一個我們先應用侵蝕然後再膨脹的過程。關閉正好相反,我們應用膨脹然後侵蝕。

讓我們使用 OpenCV 實現幾個操作。我們需要匯入所需的庫。

在這一行中,我們使用 imread() 函式讀取我們的影象,並將影象的路徑作為引數提供,並將其儲存在名為 imagedata_original 的變數中。

imagedata_original = cv2.imread("input.png")

在這段程式碼中,我們使用 numpy``ones() 函式定義 5x5 畫素的核心,核心的資料型別是無符號 int

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

我們使用 erode() 函式在下一行應用侵蝕。它需要幾個引數,如原始影象、核心和迭代。

iterations 建議你要執行侵蝕過程的次數。如果你增加這個數字,你正在增加侵蝕的影響。

erosion_op = cv2.erode(imagedata_original, kernel, iterations=1)

我們將使用 dilate() 函式將膨脹應用於影象物件。引數類似於 erode() 函式中定義的引數。

dilation_op = cv2.dilate(imagedata_original, kernel, iterations=1)

現在我們將使用 morphologyEx() 函式來應用開運算。這個函式接受像輸入影象 MORPH_OPEN 這樣的引數,它表示要應用的開啟操作,以及我們上面定義的核心。

opening_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_OPEN, kernel)

我們給出下一條指令,將關閉操作應用於 morphologyEx() 函式。

closing_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_CLOSE, kernel)

完整的原始碼:

import cv2
import numpy as np
import matplotlib.pyplot as plot

FIG = plot.figure(figsize=(6, 5))

imagedata_original = cv2.imread("input.png")

FIG.add_subplot(2, 3, 1)
plot.imshow(imagedata_original)
plot.axis("off")
plot.title("original imagge")

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

erosion_op = cv2.erode(imagedata_original, kernel, iterations=1)
FIG.add_subplot(2, 3, 2)
plot.imshow(erosion_op)
plot.axis("off")
plot.title("Erossion operatiopn")

dilation_op = cv2.dilate(imagedata_original, kernel, iterations=1)
FIG.add_subplot(2, 3, 3)
plot.imshow(dilation_op)
plot.axis("off")
plot.title("Dilation operatiopn")

opening_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_OPEN, kernel)
FIG.add_subplot(2, 3, 4)
plot.imshow(opening_op)
plot.axis("off")
plot.title("Opening operatiopn")

closing_op = cv2.morphologyEx(imagedata_original, cv2.MORPH_CLOSE, kernel)
FIG.add_subplot(2, 3, 5)
plot.imshow(closing_op)
plot.axis("off")
plot.title("Clossing operatiopn")

plot.tight_layout()
plot.show()

讓我們使用 matplotlib 在影象中執行並檢視具有不同操作的不同輸出。

侵蝕和擴張不同的輸出

大多數人可能會感到困惑,為什麼當從邊界移除畫素時,侵蝕影象中的文字顯得很粗?為什麼膨脹影象的文字在向物件的邊界新增畫素時顯得很薄。

這是因為 OpenCV 將白色部分視為物件本身,而不是將黑色文字視為影象中的物件。因此,當我們應用侵蝕操作時,它會從黑色邊界中移除白色畫素,這就是黑色文字邊界變粗的原因。

膨脹操作將白色畫素新增到黑色文字的邊界;這就是黑色文字變薄的原因。

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

相關文章 - Python OpenCV