opencv學習(二十三):形態學操作
影象的形態學處理
數學形態學(Mathematical morphology)是一門 建立在格論和拓撲學基礎之上的影象分析學科,是數學形態學影象處理的基本理論。其基本的運算包括:腐蝕和膨脹、開運算和閉運算、骨架抽取、極限腐蝕、擊中擊不中變換、形態學梯度、Top-hat變換、顆粒分析、流域變換等。
膨脹、腐蝕、開運算和閉運算是數學形態學的四個基本運算,它們在二值影象和灰度影象中各有特點。基於這些運算還可推導和組合成各種數學形態學實用演算法,用它們可以進行影象形狀和結構的分析和處理,包括影象分割、特徵提取、邊緣檢測、影象濾波、影象增強和恢復等。有關數學形態學更多的介紹,可以檢視百度詞條:數學形態學。
簡單來講,形態學操作就是基於形狀的一系列影象處理操作。opencv為進行影象的形態學變換提供了快捷,方便的函式,最基本的形態學操作有二種,他們是:膨脹和腐蝕(Dilation與Erosion)
膨脹與腐蝕能實現多種多樣的功能,主要如下:
- 消除噪聲
- 分割(isolate)出獨立的影象元素,在影象中連線(join)相鄰的元素。
- 尋找影象中的明顯的極大值區域或極小值區域
- 求出影象的梯度
在進行腐蝕和膨脹的講解之前,首先需要注意: 腐蝕和膨脹是對白色部分(高亮部分)而言的,不是黑色部分。 膨脹就是影象中的高亮部分進行膨脹,“鄰域擴張”,效果圖擁有比原圖更大的高亮區域。腐蝕就是原圖中高亮部分被腐蝕,“鄰域被蠶食”,效果圖擁有比原圖更小的高亮區域。
影象的膨脹和腐蝕
定義結構元素是數學形態學處理的核心,在OpenCV中可以使用其自帶的getStructuringElemet函式,也可以直接使用numpy陣列來定義一個結構元素。
膨脹
其實,膨脹就是求區域性最大值的操作。
按數學方面來說,膨脹或者腐蝕操作就是將影象(或影象的一部分割槽域,我們稱之為A)與核(我們稱之為B)進行卷積。
核可以是任何的形狀和大小,它擁有一個單獨定義出來的參考點,我們稱其為錨點(anchorpoint)。多數情況下,核是一個小的中間帶有參考點和實心正方形或者圓盤,其實,我們可以把核視為模板或者掩碼。
而膨脹就是求區域性最大值的操作,核B與圖形卷積,即計算核B覆蓋的區域的畫素點的最大值,並把這個最大值賦值給參考點指定的畫素。這樣就會使影象中的高亮區域逐漸增長。如下圖所示,這就是膨脹操作的初衷。
膨脹的數學表示式:
膨脹效果圖(毛筆字):
腐蝕
再來看一下腐蝕,,大家應該知道,膨脹和腐蝕是一對好基友,是相反的一對操作,所以腐蝕就是求區域性最小值的操作,我們一般都會把腐蝕和膨脹對應起來理解和學習。下文就可以看到,兩者的函式原型也是基本上一樣的。
原理圖:
腐蝕的數學表示式:
腐蝕效果圖(毛筆字):
例項演示:
程式碼如下:
#匯入cv模組
import cv2 as cv
import numpy as np
def erode_demo(image):#腐蝕
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary image",binary)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(15,15))#得到結構矩形
dst=cv.erode(binary,kernel)
cv.imshow("erode_demo",dst)
def dilate_demo(image):#膨脹
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary image",binary)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(15,15))#得到結構矩形
dst=cv.dilate(binary,kernel)
cv.imshow("dilate_demo",dst)
print("------------Python Opencv Tutorial!-------------")
# 讀取影象,支援 bmp、jpg、png、tiff 等常用格式
# src = cv.imread("F:/Projects/images/5.png")
src = cv.imread("F:/Projects/images/bin2.png")
#建立視窗並顯示影象
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",src) #顯示原圖
erode_demo(src)
dilate_demo(src)
cv.waitKey(0)
#釋放視窗
cv.destroyAllWindows()
執行效果:
參考連結:https://www.cnblogs.com/wyuzl/p/6262714.html