設(shè)計(jì)風(fēng)格網(wǎng)站欣賞怎么創(chuàng)建網(wǎng)站快捷方式到桌面
文章目錄
- 概要
- 目標(biāo)
- 腐蝕
- 膨脹
- 開運(yùn)算
- 結(jié)構(gòu)元素(內(nèi)核)
- 小結(jié)
概要
形態(tài)學(xué)變化是一組簡單的圖像操作,主要用于處理二值圖像,即只包含黑和白兩種顏色的圖像。這些操作通常需要兩個(gè)輸入,原始圖像和一個(gè)內(nèi)核(kernel),內(nèi)核的形狀和大小決定了操作的性質(zhì)。
文章將首先介紹腐蝕和膨脹這兩個(gè)基本的形態(tài)學(xué)算子。腐蝕操作通過內(nèi)核在圖像上滑動(dòng),將像素值置為內(nèi)核覆蓋區(qū)域內(nèi)的最小值,用于消除圖像中的小物體或者噪點(diǎn)。相反,膨脹操作將像素值置為內(nèi)核覆蓋區(qū)域內(nèi)的最大值,常用于連接圖像中的物體或者填充小的空洞。
隨后,文章將介紹其他常見的形態(tài)學(xué)算子,如開運(yùn)算和閉運(yùn)算。開運(yùn)算是先進(jìn)行腐蝕操作,再進(jìn)行膨脹操作,常用于去除噪聲和分離物體。閉運(yùn)算則是先進(jìn)行膨脹操作,再進(jìn)行腐蝕操作,常用于填充小洞和連接物體
目標(biāo)
不同的形態(tài)學(xué)運(yùn)算例如腐蝕、膨脹、開運(yùn)算、閉運(yùn)算。
不同的函數(shù)列如cv.erode()、cv.dilate()、cv.morphologyEx()等等。
腐蝕
是一種基本的形態(tài)學(xué)操作,其原理類似于自然界中的水土流失現(xiàn)象。在腐蝕操作中,一個(gè)內(nèi)核(kernel)在圖像上滑動(dòng),如果內(nèi)核覆蓋下的所有像素都為1(即白色,表示前景物體),那么中心像素點(diǎn)就會(huì)被賦值為1,否則被腐蝕掉(賦值為0)。
這種操作導(dǎo)致了圖像中前景物體的邊界被侵蝕,保持前景物體為白色的同時(shí),減小了其厚度或尺寸。換句話說,圖像中的白色區(qū)域會(huì)逐漸減小。腐蝕操作在去除小白點(diǎn)噪聲(例如圖像中的小雜點(diǎn))和分離連接在一起的對象等方面非常有效。通過選擇合適的內(nèi)核大小,可以調(diào)整腐蝕的程度,使其更加適應(yīng)不同場景下的圖像處理需求。
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)# 使用腐蝕操作,iterations參數(shù)表示腐蝕操作的次數(shù)
erosion = cv.erode(img, kernel, iterations=1)# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示腐蝕后的圖像
cv.imshow('Eroded Image', erosion)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
腐蝕結(jié)果:
膨脹
膨脹是一種形態(tài)學(xué)操作,與腐蝕相反。它的基本思想是通過內(nèi)核的滑動(dòng),只要內(nèi)核下的像素中有一個(gè)為1,中心像素就會(huì)被賦值為1(這類似于邏輯或運(yùn)算)。膨脹操作會(huì)擴(kuò)大白色物體(或前景物體)的區(qū)域或大小。在去除噪聲時(shí),通常會(huì)先進(jìn)行腐蝕操作,然后再進(jìn)行膨脹操作。這是因?yàn)楦g能夠去除小的白色噪聲,但同時(shí)也可能腐蝕掉我們需要保留的物體。膨脹操作的目的就是擴(kuò)大物體,使其恢復(fù)到原始大小和形狀。
在膨脹操作中,噪聲已經(jīng)在腐蝕階段被去除,因此在膨脹時(shí)不會(huì)再次引入噪聲,但物體的大小和體積會(huì)得到恢復(fù)。此外,膨脹操作還對有破損或間斷連接的物體部分進(jìn)行恢復(fù),使其更加完整。通過膨脹操作,可以使圖像中的白色區(qū)域逐漸增大,從而更好地突出物體的特征。
開運(yùn)算
開運(yùn)算只是先腐蝕后膨脹的另一個(gè)名稱。正如我們上面所解釋的,它對于消除噪音很有用。這里我們函數(shù)cv.morphologyEx()。
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)# 使用開運(yùn)算,先腐蝕后膨脹,可以去除噪聲并保持物體的整體形狀
opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示開運(yùn)算后的圖像
cv.imshow('Opened Image', opening)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
閉運(yùn)算
閉運(yùn)算和開運(yùn)算相反,先膨脹后腐蝕。它對于關(guān)閉前景對象內(nèi)的小孔或?qū)ο笊系男『邳c(diǎn)非常有用。
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)# 使用閉運(yùn)算,先膨脹后腐蝕,可以填充前景物體內(nèi)部的小孔,平滑物體的邊界
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示閉運(yùn)算后的圖像
cv.imshow('Closed Image', closing)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
形態(tài)梯度
這是圖像的膨脹和腐蝕之間做了一次差
結(jié)果將看起來像只留下對象的輪廓。
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)# 使用形態(tài)梯度,通過膨脹和腐蝕的差別,突出物體的邊緣
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示形態(tài)梯度后的圖像
cv.imshow('Gradient Image', gradient)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
頂帽
它是輸入圖像和開運(yùn)算圖像之間的差。下面的示例是針對 9x9 內(nèi)核完成的。
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示形態(tài)梯度后的圖像
cv.imshow('Gradient Image', tophat)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
底帽
它是閉運(yùn)算圖像和輸入圖像的差
import cv2 as cv
import numpy as np# 讀取圖像
img = cv.imread('img.png', 0)# 創(chuàng)建一個(gè) 5x5 的內(nèi)核(矩陣)
kernel = np.ones((5, 5), np.uint8)blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
# 顯示原始圖像
cv.imshow('Original Image', img)# 顯示形態(tài)梯度后的圖像
cv.imshow('Gradient Image', blackhat)# 等待用戶按下任意鍵后關(guān)閉窗口
cv.waitKey(0)
cv.destroyAllWindows()
結(jié)構(gòu)元素(內(nèi)核)
在形態(tài)學(xué)變換中,我們經(jīng)常需要定義一個(gè)內(nèi)核來指導(dǎo)圖像處理。在前面的例子中,我們手動(dòng)創(chuàng)建了一個(gè)矩形內(nèi)核,但在實(shí)際應(yīng)用中,可能需要不同形狀和大小的內(nèi)核。為了方便地獲取這些內(nèi)核,OpenCV提供了一個(gè)函數(shù)cv.getStructuringElement()。
使用該函數(shù),您只需要傳遞內(nèi)核的形狀和大小,就可以獲得所需的內(nèi)核。
cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
如果需要一個(gè)橢圓形內(nèi)核,可以使用以下代碼:
cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
類似地,如果需要一個(gè)十字形內(nèi)核,可以使用
cv.getStructuringElement(cv.MORPH_CROSS, (5, 5))
小結(jié)
形態(tài)學(xué)變換是一種基于圖像形狀的簡單而有效的處理方法,通常應(yīng)用于二值圖像(只包含黑白兩種顏色)。在形態(tài)學(xué)變換中,我們使用內(nèi)核(也稱為結(jié)構(gòu)化元素)來定義操作的性質(zhì)和形狀。
腐蝕是一種形態(tài)學(xué)變換,它侵蝕了前景物體(白色區(qū)域)的邊界,通常用于去除小白點(diǎn)噪聲或分離連接的對象。使用cv.erode()函數(shù),我們可以將內(nèi)核滑動(dòng)在圖像上,將內(nèi)核覆蓋下的像素點(diǎn)都為1時(shí),中心像素點(diǎn)就會(huì)被賦值為1,其他時(shí)候都為0,從而縮小白色區(qū)域。
膨脹則與腐蝕相反,它會(huì)擴(kuò)大白色物體的區(qū)域,常用于恢復(fù)連接對象的大小和形狀。使用cv.dilate()函數(shù),內(nèi)核覆蓋下的像素點(diǎn)只需有一個(gè)為1,中心像素點(diǎn)就會(huì)被賦值為1,從而擴(kuò)大白色區(qū)域。
開運(yùn)算是先腐蝕后膨脹的組合操作,它可以去除噪聲并保持物體的整體形狀。閉運(yùn)算則是先膨脹后腐蝕的組合操作,它可以填充前景物體內(nèi)部的小孔,平滑物體的邊界。這兩種操作分別使用cv.morphologyEx()函數(shù)中的cv.MORPH_OPEN和cv.MORPH_CLOSE參數(shù)實(shí)現(xiàn)。
為了方便地定義不同形狀和大小的內(nèi)核,OpenCV提供了cv.getStructuringElement()函數(shù)。通過傳遞內(nèi)核的形狀和大小參數(shù),可以獲得所需的內(nèi)核。矩形、橢圓和十字形內(nèi)核是常見的選擇,可以根據(jù)具體任務(wù)的要求靈活選擇合適的內(nèi)核形狀。