型態學,即數學型態學(Mathematical Morphology),型態學主要從影像內分析分量資訊,該分量資訊通常對於表達和描繪影像的形狀具有重要意義,通常是影像了解時所使用的最本質的形狀特徵。
型態學包含:腐蝕、膨脹、開運算、閉運算、型態學梯度運算、頂帽運算、黑帽運算等操作。
腐蝕是最基本的型態學操作之一,它能夠將影像的邊界點消除,使影像沿著邊界像內收縮,也可以將小於指定結構元素的部分去除。
腐蝕用來「收縮」或「細化」二值影像中的前景,藉此實現去除雜訊、元素分割等功能。
腐蝕是針對白色部分(高亮部分)而言的。
腐蝕是原圖中的高亮區域被蠶食,效果圖擁有比原圖更小的高亮區域(黑暗放大,光亮縮小)。
在OpenCV中,使用函數cv2.erode()來實現腐蝕操作:
dst = cv2.erode(src , kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
dst 是腐蝕後所輸出的靶心圖表面。
src是需要進行腐蝕的原始影像。
kernel(核)代表腐蝕操作時所採用的結構類型,可以自訂也可以透過函數cv2.getStructuringElement()產生
anchor代表element結構中錨點的位置。該值預設為(-1,-1)。
iterations是腐蝕操作反覆運算的次數,該預設值為1。
borderType代表邊界樣式,一般採用預設值BORDER_CONSTANT。
borderValue代表邊界值,一般採用預設值。
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
erosion1 = cv2.erode(img ,kernel) #iterations使用預設值,故只有一次
erosion5 = cv2.erode(img , kernel ,iterations =5) #使其反覆運算五次
可以看到,影象原來黑暗的部分被放大了,明亮的部分被縮小了。
膨脹與腐蝕的作用是相反的,膨脹操作能對影像的邊界進行擴張。
膨脹是針對白色部分(高亮部分)而言的。
膨脹就是對影象高亮部分進行“領域擴張”,效果圖擁有比原圖更大的高亮區域
膨脹就是求區域性最大值的操作,從影象直觀看來,就是將影象光亮部分放大,黑暗部分縮小。
在OpenCV內,採用函數cv2.dilate()實現對影像的膨脹操作:
dst = cv2.dilate(src , kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
代表意義與腐蝕相同。
kernel = np.ones((100,100),np.uint8) #產生5*5的核(kernel)
dilation1 = cv2.dilate(img ,kernel)
dilation5 = cv2.dilate(img , kernel ,iterations =5) #使其反覆運算五次
可以看到,影象原來光亮的部分被放大了,黑暗的部分被縮小了。
腐蝕和膨脹都是型態學運算的基礎,將腐蝕和膨脹進行組合,就可以實現開運算、閉運算、型態學梯度運算、頂冒運算、黑帽運算等多種不同形式的運算
OpenCV提供了函數cv2.morphologyEx()來實現上述型態學運算:
dst = cv2.morphologyEx( src , op ,kernel[, anchor[, iterations[, borderType[, borderValue]]]]])
dst 代表經過型態學處理後所輸出的靶心圖表面。
src代表原始影像。
op代表操作類型。
其他參數與erode()一致。
開運算進行的操作是將影像腐蝕、再對腐蝕的結果進行膨脹,可用於去噪(消除小物體)、計數或去除物體上的小白點等。
透過函數cv2.morphologyEx()中操作類型op設定為"cv2.MORPH_OPEN",可以實現開運算:
opening = cv2.morphologyEx(img , cv2.MORPH_OPEN, kernel)
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
opening = cv2.morphologyEx(img ,cv2.MORPH_OPEN,kernel)
可明顯看出白色的小物體都被消除!
閉運算是先膨脹、後腐蝕的運算,它有助關閉前景物體內部的小孔,或去除物體上的小黑點,還可以將不同的前景影像進行連接。
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
close = cv2.morphologyEx(img ,cv2.MORPH_CLOSE,kernel)
型態學梯度運算是用影像的膨脹影像減腐蝕影像,該操作可以取得原始影像中前景影像的邊緣。
result = cv2.morphologyEx(img , cv2.MORPH_GRADIENT, kernel)
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
res = cv2.morphologyEx(img ,cv2.MORPH_GRADIENT,kernel)
頂帽運算是用原始影像減去開運算影像的操作,能取得雜訊資訊或比原始影像的邊緣更亮的邊緣資訊。
result = cv2.morphologyEx(img , cv2.MORPH_TOPHAT,kernel)
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
res = cv2.morphologyEx(img ,cv2.MORPH_TOPHAT,kernel)
可以看出邊緣資訊更加明顯!
黑帽運算是用閉運算影像減去原始影像的操作,能取得影像內部的小孔、前景色中的小黑點、比原始影像的邊緣更暗的邊緣部分。
result = cv2.morphologyEx(img , cv2.MORPH_BLACKHAT,kernel)
kernel = np.ones((5,5),np.uint8) #產生5*5的核(kernel)
res = cv2.morphologyEx(img ,cv2.MORPH_BLACKHAT,kernel)