1. 程式人生 > >形態學影象處理:膨脹與腐蝕

形態學影象處理:膨脹與腐蝕

形態學(morphology)一詞通常表示生物學的一個分支,該分支主要研究動植物的形態和結構。而我們影象處理中指的形態學,往往表示的是數學形態學。下面一起來了解數學形態學的概念。

數學形態學(Mathematical morphology) 是一門建立在格論和拓撲學基礎之上的影象分析學科,是數學形態學影象處理的基本理論。其基本的運算包括:二值腐蝕和膨脹、二值開閉運算、骨架抽取、極限腐蝕、擊中擊不中變換、形態學梯度、Top-hat變換、顆粒分析、流域變換、灰值腐蝕和膨脹、灰值開閉運算、灰值形態學梯度等。

簡單來講,形態學操作就是基於形狀的一系列影象處理操作。OpenCV為進行影象的形態學變換提供了快捷、方便的函式。最基本的形態學操作有二種,他們是:膨脹與腐蝕(Dilation與Erosion)。

膨脹與腐蝕能實現多種多樣的功能,主要如下:

  • 消除噪聲
  • 分割(isolate)出獨立的影象元素,在影象中連線(join)相鄰的元素。
  • 尋找影象中的明顯的極大值區域或極小值區域
  • 求出影象的梯度

腐蝕和膨脹是對白色部分(高亮部分)而言的,不是黑色部分。膨脹就是影象中的高亮部分進行膨脹,“領域擴張”,效果圖擁有比原圖更大的高亮區域。腐蝕就是原圖中的高亮部分被腐蝕,“領域被蠶食”,效果圖擁有比原圖更小的高亮區域。

膨脹就是求區域性最大值的操作。

按數學方面來說,膨脹或者腐蝕操作就是將影象(或影象的一部分割槽域,我們稱之為A)與核(我們稱之為B)進行卷積。

可以是任何的形狀和大小,它擁有一個單獨定義出來的參考點,我們稱其為錨點(anchorpoint)。多數情況下,核是一個小的中間帶有參考點和實心正方形或者圓盤,其實,我們可以把核視為模板或者掩碼。

而膨脹就是求區域性最大值的操作,核B與圖形卷積,即計算核B覆蓋的區域的畫素點的最大值,並把這個最大值賦值給參考點指定的畫素。這樣就會使影象中的高亮區域逐漸增長。如下圖所示,這就是膨脹操作的初衷。

形態學膨脹用dilate函式,形態學腐蝕用erode函式。

示例:

//-----------------------------------【標頭檔案包含部分】---------------------------------------
// 描述:包含程式所依賴的標頭檔案 //---------------------------------------------------------------------------------------------- #include "pch.h" #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> #include <iostream> //-----------------------------------【名稱空間宣告部分】--------------------------------------- // 描述:包含程式所使用的名稱空間 //----------------------------------------------------------------------------------------------- using namespace std; using namespace cv; //-----------------------------------【全域性變數宣告部分】-------------------------------------- // 描述:全域性變數宣告 //----------------------------------------------------------------------------------------------- Mat g_srcImage, g_dstImage;//原始圖和效果圖 int g_nTrackbarNumer = 0;//0表示腐蝕erode, 1表示膨脹dilate int g_nStructElementSize = 3; //結構元素(核心矩陣)的尺寸 //-----------------------------------【全域性函式宣告部分】-------------------------------------- // 描述:全域性函式宣告 //----------------------------------------------------------------------------------------------- void Process();//膨脹和腐蝕的處理函式 void on_TrackbarNumChange(int, void *);//回撥函式 void on_ElementSizeChange(int, void *);//回撥函式 //-----------------------------------【main( )函式】-------------------------------------------- // 描述:控制檯應用程式的入口函式,我們的程式從這裡開始 //----------------------------------------------------------------------------------------------- int main() { //改變console字型顏色 system("color5E"); //載入原圖 g_srcImage = imread("1.jpg"); if (!g_srcImage.data) { printf("讀取srcImage錯誤\n"); return false; } //顯示原始圖 namedWindow("【原始圖】"); imshow("【原始圖】", g_srcImage); //進行初次腐蝕操作並顯示效果圖 namedWindow("【效果圖】"); //獲取自定義核 Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize)); erode(g_srcImage, g_dstImage, element); imshow("【效果圖】", g_dstImage); //建立軌跡條 createTrackbar("腐蝕/膨脹", "【效果圖】", &g_nTrackbarNumer, 1, on_TrackbarNumChange); createTrackbar("核心尺寸", "【效果圖】", &g_nStructElementSize, 21, on_ElementSizeChange); //輸出一些幫助資訊 cout << endl << "\t執行成功,請調整滾動條觀察影象效果~\n\n" << "\t按下“q”鍵時,程式退出~!\n"; //輪詢獲取按鍵資訊,若下q鍵,程式退出 while (char(waitKey(1)) != 'q') {} return 0; } //-----------------------------【Process( )函式】------------------------------------ // 描述:進行自定義的腐蝕和膨脹操作 //----------------------------------------------------------------------------------------- void Process() { //獲取自定義核 Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize)); //進行腐蝕或膨脹操作 if (g_nTrackbarNumer == 0) { erode(g_srcImage, g_dstImage, element); } else { dilate(g_srcImage, g_dstImage, element); } //顯示效果圖 imshow("【效果圖】", g_dstImage); } //-----------------------------【on_TrackbarNumChange( )函式】------------------------------------ // 描述:腐蝕和膨脹之間切換開關的回撥函式 //----------------------------------------------------------------------------------------------------- void on_TrackbarNumChange(int, void *) { //腐蝕和膨脹之間效果已經切換,回撥函式體內需呼叫一次Process函式,使改變後的效果立即生效並顯示出來 Process(); } //-----------------------------【on_ElementSizeChange( )函式】------------------------------------- // 描述:腐蝕和膨脹操作核心改變時的回撥函式 //----------------------------------------------------------------------------------------------------- void on_ElementSizeChange(int, void *) { //核心尺寸已改變,回撥函式體內需呼叫一次Process函式,使改變後的效果立即生效並顯示出來 Process(); }

腐蝕效果:
腐蝕

膨脹效果:
膨脹

參考:
獲取自定義核getStructuringElement
腐蝕erode
膨脹dilate