公司門戶網(wǎng)站建設(shè)策劃書朔州網(wǎng)站seo
前置
形態(tài)學(xué)主要是從圖像中提取分量信息,該分量信息通常是圖像理解時(shí)所使用的最本質(zhì)的形狀特征,對(duì)于表達(dá)和描繪圖像的形狀有重要意義。
大體就是通過一系列操作讓圖像信息中的關(guān)鍵信息更加凸出。同時(shí),形態(tài)學(xué)的操作都是基于灰度圖進(jìn)行。
相關(guān)操作最主要的2種操作為腐蝕/膨脹,后面又延伸了綜合操作-開運(yùn)算/閉運(yùn)算/形態(tài)學(xué)梯度/禮帽/黑帽等等。
腐蝕
腐蝕是最基本的形態(tài)學(xué)操作之一,能夠去除圖像的邊界點(diǎn),使圖像沿著邊界向內(nèi)收縮,對(duì)于小于指定結(jié)構(gòu)元的部分會(huì)去除。
所以,通過腐蝕可以達(dá)到去除一些外部噪音、元素分割等功能。
腐蝕原理說明 :
結(jié)構(gòu)元 : 就是擁有一個(gè)中心位置并且有一定范圍的結(jié)構(gòu),說白了就是一個(gè)二維數(shù)組。
掃描圖像中的每一個(gè)像素點(diǎn),結(jié)構(gòu)元和掃描點(diǎn)重合,用結(jié)構(gòu)元元素與覆蓋的二值圖做"與"運(yùn)算,都為1則圖像的像素值不變,否則改為0。
圖示如下:
a圖為原圖,b圖為結(jié)構(gòu)元,當(dāng)掃描到第2行,由于第一行存在2/3/4列的數(shù)據(jù)為0,所以經(jīng)過腐蝕后,第2行的2/3/4列的1都變成了0,同理第4行。
掃描到第三行的2/3/4列時(shí),由于都是1,第3行的2/3/4列分別不變,最終結(jié)果如d圖所示。
函數(shù)語法說明: dst = cv2.erode( src,kernel,anchor,iterations,borderType,borderValue)
- kernel : 腐蝕時(shí)使用的結(jié)構(gòu)體,可以自己生成,也可以通過cv2.getStructuringElement()生成,就是個(gè)二維數(shù)組空間
- anchor : 錨點(diǎn)位置,默認(rèn)為(-1,-1),在核的中心位置
- iterations : 腐蝕操作迭代次數(shù),默認(rèn)為1,只進(jìn)行1次腐蝕操作
- borderType : 邊界處理方式,一般采用默認(rèn)BORDER_CONSTANT
- borderValue : 邊界填充值,一般采用默認(rèn)值
所以經(jīng)常簡(jiǎn)化為 dst = cv2.erode( src ,kernel )
程序?qū)嵗缦?
import cv2 as cv
import numpy as nporigin = cv.imread("erode.bmp")
# 使用了一個(gè)3*3的結(jié)構(gòu)元,結(jié)構(gòu)元面積越大,腐蝕的越厲害,結(jié)果圖就越小
kernel_3 = np.ones((3, 3), np.uint8)# 不大明顯,但有些觸角已經(jīng)變短了
erode_3 = cv.erode(origin, kernel_3)
# 反復(fù)刷了三次,圖像進(jìn)一步腐蝕減小,邊角已經(jīng)腐蝕掉了
erode_3_3 = cv.erode(origin, kernel_3, iterations=3)cv.imshow("origin", origin)
cv.imshow("erode_3", erode_3)
cv.imshow("erode_3_3", erode_3_3)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行結(jié)果如下:
?膨脹
膨脹操作同樣是形態(tài)學(xué)的一種基本操作,膨脹和腐蝕的作用是相反的,膨脹操作能對(duì)邊界進(jìn)行擴(kuò)張。膨脹操作可以將較近的2個(gè)對(duì)象連通在一起,也有利于填補(bǔ)
圖片分割后圖像內(nèi)的空白處。
膨脹原理說明:
使用結(jié)構(gòu)元掃描圖像中的每一個(gè)像素點(diǎn),結(jié)構(gòu)元和掃描點(diǎn)重合,用結(jié)構(gòu)元元素與覆蓋的二值圖做"與"運(yùn)算,都為0則圖像的像素值為0,否則改為1,這樣圖片邊緣位置就會(huì)緊跟結(jié)構(gòu)元進(jìn)行擴(kuò)張。
函數(shù)語法說明: dst = cv2.dilate( src ,kernel,anchor,iterations,borderType,borderValue)
函數(shù)參數(shù)與腐蝕參數(shù)完全一致,不做過多解釋。方法可以簡(jiǎn)化為 dst = cv2.dilate( src,kernel )
程序?qū)嵗缦?
import cv2 as cv
import numpy as nporigin = cv.imread("dilation.png")
# 使用了一個(gè)3*3的結(jié)構(gòu)元,結(jié)構(gòu)元面積越大,膨脹的越厲害,結(jié)果圖就越大
kernel = np.ones((3, 3), np.uint8)
erode_3 = cv.dilate(origin, kernel)
# 連續(xù)膨脹3次
erode_3_3 = cv.dilate(origin, kernel, iterations=9)
cv.imshow("origin", origin)
cv.imshow("dilation_3", erode_3)
cv.imshow("dilation_3_3", erode_3_3)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行如下:
?
開運(yùn)算
開運(yùn)算是先進(jìn)行腐蝕操作,后再進(jìn)行膨脹操作。進(jìn)行腐蝕操作可以把圖像中目標(biāo)外的噪聲去掉,膨脹后再恢復(fù)目標(biāo)的大小。
函數(shù)語法說明: dst = cv2.morphologyEx( src,cv2.MORPH_OPEN,kernel)
src,dst分別是原始圖像和處理后的結(jié)果圖像
cv2.MORPH_OPEN : 做開運(yùn)算的標(biāo)識(shí)
kernel : 運(yùn)算使用的結(jié)構(gòu)元
程序如下:
import cv2 as cv
import numpy as nporigin = cv.imread("open_pic.png", 0)
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_OPEN, kernel) # 開運(yùn)算
cv.imshow("origin", origin)
cv.imshow("open", open_pic)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行如下:
?
閉運(yùn)算
閉運(yùn)算是先進(jìn)行膨脹操作,后再進(jìn)行腐蝕操作。主要針對(duì)情景為圖像中關(guān)鍵信息內(nèi)部有小洞,膨脹操作會(huì)填充小洞。
函數(shù)語法說明: dst = cv2.morphologyEx( src,cv2.MORPH_CLOSE,kernel)
閉運(yùn)算和開運(yùn)算使用一樣的函數(shù),僅通過標(biāo)識(shí)不同來實(shí)現(xiàn)不同操作。
cv2.MORPH_OPEN : 做閉運(yùn)算的標(biāo)識(shí)
程序如下:
import cv2 as cv
import numpy as nporigin = cv.imread("close_pic.png", 0)
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_CLOSE, kernel) # 閉運(yùn)算
cv.imshow("origin", origin)
cv.imshow("open", open_pic)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行結(jié)果如下:
?
形態(tài)學(xué)梯度
其實(shí)就是一副圖像膨脹和腐蝕的差別,看起來就是前景物體的輪廓。
函數(shù)語法說明:dst = cv2.morphologyEx( src,cv2.MORPH_GRADIENT,kernel)
函數(shù)同開閉運(yùn)算一樣,只有樣式不一樣。
cv2.MORPH_GRADIENT : 形態(tài)學(xué)梯度的關(guān)鍵字
程序如下:
import cv2 as cv
import numpy as nporigin = cv.imread("abcdefg.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_GRADIENT, kernel) # 形態(tài)學(xué)梯度
cv.imshow("origin", origin)
cv.imshow("gradient", open_pic)cv.waitKey()
cv.destroyAllWindows()
效果圖如下:
?
禮帽
開運(yùn)算是先腐蝕再膨脹,會(huì)消除圖像中的噪聲,而禮帽是原始圖片與進(jìn)行開運(yùn)算后的得到的圖像的差,也就是消除掉的噪聲。
函數(shù)語法說明: dst = cv2.morphologyEx( src,cv2.MORPH_TOPHAT,kernel)
import cv2 as cv
import numpy as nporigin = cv.imread("open_pic.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_TOPHAT, kernel) # 禮帽
cv.imshow("origin", origin)
cv.imshow("tophat", open_pic)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行如下:
?
黑帽
閉運(yùn)算是先膨脹再腐蝕,具有填充內(nèi)部小洞的功能,而黑帽是進(jìn)行閉運(yùn)算得到的圖片與原始圖像的差,所以顯示的是之前補(bǔ)上的小洞圖片。
函數(shù)語法說明: dst = cv2.morphologyEx( src,cv2.MORPH_BLACKHAT,kernel)
程序如下:
import cv2 as cv
import numpy as nporigin = cv.imread("close_pic.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_BLACKHAT, kernel) # 黑帽
cv.imshow("origin", origin)
cv.imshow("blackhat", open_pic)cv.waitKey()
cv.destroyAllWindows()
運(yùn)行如下:
?
?