OpenCV二值圖像分析之形態(tài)學應用技巧
點擊上方“小白學視覺”,選擇加"星標"或“置頂”
重磅干貨,第一時間送達
本文轉自:opencv學堂
前兩天剛寫了一篇二值圖像分析之輪廓發(fā)現(xiàn)與輪廓屬性分析的相關文章,得到大家比較好反饋,感謝大家支持,讓我有勇氣繼續(xù)再寫下去,二值圖像分析還有一塊核心技能就是圖像形態(tài)學操作技巧,這里也打算根據(jù)我自己的項目經(jīng)驗,給大家吐槽總結一下,希望大家多提寶貴意見,不足之處多多補充!
OpenCV中支持的圖像形態(tài)學操作主要有膨脹、腐蝕、開操作、閉操作、頂帽操作、黑帽操作、形態(tài)學梯度操作,涉及的相關API函數(shù)主要有如下幾個:
腐蝕操作函數(shù):
void cv::erode(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
膨脹操作函數(shù):
1void cv::dilate(
2 InputArray src,
3 OutputArray dst,
4 InputArray kernel,
5 Point anchor = Point(-1,-1),
6 int iterations = 1,
7 int borderType = BORDER_CONSTANT,
8 const Scalar & borderValue = morphologyDefaultBorderValue()
9)
腐蝕跟膨脹兩個函數(shù)的高度相似,唯一不同的函數(shù)運行輸出結果不一樣。參數(shù)解釋如下:
src 輸入圖像、灰度或者彩色均可
dst 輸出圖像、跟輸入圖像格式與類型相同
kernel 結構元素、決定輸出圖像樣式
anchor 錨定位置、是針對結構元素來說的
iterations 循環(huán)次數(shù)、意思是連續(xù)多次操作(腐蝕/膨脹)
borderType 邊緣處理、邊緣處理的方式,這個以前也詳細的講過,這里不廢話了
borderValue 只有在選擇DEFAULT_BORDER的時候才會用。
獲取結構元素:
1Mat cv::getStructuringElement(
2 int shape,
3 Size ksize,
4 Point anchor = Point(-1,-1)
5)
參數(shù)解釋:
shape:是指結構元素的形狀,常見的有矩形、圓形、十字交叉、線
ksize:是指結構元素的大小
anchor:是指結構元素錨定的位置、Point(-1,-1)表示默認錨定位置為結構元素中心
形態(tài)學操作函數(shù):
1void cv::morphologyEx(
2 InputArray src,
3 OutputArray dst,
4 int op,
5 InputArray kernel,
6 Point anchor = Point(-1,-1),
7 int iterations = 1,
8 int borderType = BORDER_CONSTANT,
9 const Scalar & borderValue = morphologyDefaultBorderValue()
10)
該函數(shù)通過其中操作(op)參數(shù)來實現(xiàn)OpenCV支持全部形態(tài)學操作、當然包括腐蝕與膨脹、所以可以忘記腐蝕跟膨脹單獨的函數(shù)表達了。該函數(shù)與腐蝕/膨脹函數(shù)相比,多出唯一參數(shù)是op操作,當前支持的操作包括如下:
1MORPH_ERODE 腐蝕
2MORPH_DILATE 膨脹
3MORPH_OPEN 開操作
4MORPH_CLOSE 閉操作
5MORPH_GRADIENT 形態(tài)學梯度
6MORPH_TOPHAT 頂帽操作
7MORPH_BLACKHAT 黑帽操作
8MORPH_HITMISS 擊中擊不中
這里結合每個形態(tài)學操作,給出了每個操作的應用場景與效果演示。簡單的腐蝕與膨脹操作,實現(xiàn)區(qū)域分離與合并
原圖(圖-1):

使用15x15的圓形結構元素膨脹之后:(圖-2)

使用相同的結構元素,對圖-1進行腐蝕之后:(圖-3)

可見使用15x15圓形結構元素腐蝕之后,圖中所有的對象已經(jīng)被擦除了。
原圖(圖-4):

開操作
開操作可以去除小的干擾塊,開操作結構元素:7x7矩形,開操作之后(圖-5)

可見已經(jīng)刪除一些小的干擾塊跟白色像素點了。
閉操作
閉操作可以填充空洞區(qū)域,比如圖-4中白色矩形內(nèi)部黑色部分小矩形,通過閉操作可以完成填充,使用11x11的矩形結構元素,操作之后(圖-6):

可見圖中黑色矩形區(qū)域已經(jīng)填充完成。
有時候我只對這些很小區(qū)域感興趣,特別是在工業(yè)檢測中,很多都是微小的瑕疵或者斑點,常規(guī)方法很能提取到,這個時候我們通過下面兩個形態(tài)學操作可以實現(xiàn)對這些小干擾塊/瑕疵區(qū)域的提取,原圖如下(圖-7):

這個圖是來自知識星球一位會員的提問,他想提取那個小白色斑點,并測量它的大小與面積,采用頂帽操作即可獲取,頂帽操作的定義為原圖 減去 開操作結果,只要給一個合適的結構元素,即可提取到斑點區(qū)域, 頂帽操作之后,會有一些邊緣線,通過開操作刪去,最終得到的結果如下:(圖-8)

很完美的得到圖像白色斑點區(qū)域了。
除了頂帽操作,另外還有一個黑帽操作,它的定義為閉操作的結果減去原圖,對圖-4實現(xiàn)黑帽操作就可以得到白色矩形中黑色小矩形塊,結果如下:(圖-9)

所以頂帽跟黑帽是非常有用的兩個操作,特別是在二值圖像分析中需要提取一些比較小Blob對象場景中。
形態(tài)學梯度
使用形態(tài)學梯度可以完整的提取一些對象邊緣跟輪廓,在一些應用場景中非常適用。舉例,原圖如下:(圖-10)

基于形態(tài)學梯度提取內(nèi)外輪廓,得到的邊緣圖像如下:(圖-11)

代碼都很簡單,基本都是API函數(shù)直接調用,這里就不貼出來獻丑了,主要是告訴大家如何利用OpenCV提供函數(shù)靈活運用,每個函數(shù)都有著自己合適的應用場景,形態(tài)學的各種不同結構元素跟操作有時候會給你帶來非常好的圖像處理效果,直接可以服務后續(xù)的對象檢測與測量、識別等環(huán)節(jié)。實現(xiàn)上述形態(tài)學處理的關鍵代碼就三行,如下:
1Mat src = imread("D:/images/morph.png");
2se = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
3morphologyEx(src, dst, MORPH_OPEN, se);
主要靠這三行,解釋一下!先要二值化、然后找到合適的結構元素,然后執(zhí)行對應的形態(tài)學操作,代碼中是開操作!請千萬別注意一下!
交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

