圖像腐蝕和膨脹

一、概論

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

膨脹與腐蝕是圖像的最基本的兩種變化,他們能實現的功能包括但不限於:
(1) 、消除噪聲
(2) 、分割出圖像中獨立的元素或者連接圖像中的元素
(3) 、尋找圖像中明顯的極大值區域和極小值區域
(4) 、求出圖像的梯度

需要注意的是,腐蝕和膨脹是對高亮部分(白色)來說的,圖像進行膨脹操作後,它的高亮區域將變大,圖像進行腐蝕操作後,他的高亮區域將變小。

二 、膨脹

 void dilate(
    InputArray src,
    OutputArray dst,
    InputArray kernel,
    Point anchor=Point(-1,-1),
    int iterations=1,
    int borderType=BORDER_CONSTANT,
    const Scalar& borderValue=morphologyDefaultBorderValue() 
);

參數詳解:
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。圖像通道的數量可以是任意的,但圖像深度應爲CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
第三個參數,InputArray類型的kernel,膨脹操作的核。若爲NULL時,表示的是使用參考點位於中心3x3的核。
我們一般使用函數 getStructuringElement配合這個參數的使用。getStructuringElement函數會返回指定形狀和尺寸的結構元素(內核矩陣)。
其中,getStructuringElement函數的第一個參數表示內核的形狀,我們可以選擇如下三種形狀之一:
o矩形: MORPH_RECT
o交叉形: MORPH_CROSS
o橢圓形: MORPH_ELLIPSE
而getStructuringElement函數的第二和第三個參數分別是內核的尺寸以及錨點的位置。
我們一般在調用erode以及dilate函數之前,先定義一個Mat類型的變量來獲得getStructuringElement函數的返回值。對於錨點的位置,有默認值Point(-1,-1),表示錨點位於中心。且需要注意,十字形的element形狀唯一依賴於錨點的位置。而在其他情況下,錨點只是影響了形態學運算結果的偏移。

膨脹就是局部最大值操作,其實就是將圖像與核做卷積運算的結果。核可以是任何的形狀和大小,它有一個參考點(錨點)。那麼膨脹是如何操作的呢?圖像與核覆蓋的區域求最大值,然後將這個最大值賦值給指定的像素,這樣就會使得圖像中的高亮區域逐漸增長。

膨脹的數學表達式爲:

三、腐蝕

erode(
    InputArray src,
    OutputArray dst,
    InputArray kernel,
    Point anchor=Point(-1,-1),
    int iterations=1,
    int borderType=BORDER_CONSTANT,
    const Scalar& borderValue=morphologyDefaultBorderValue()
 );

參數詳解:
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。圖像通道的數量可以是任意的,但圖像深度應爲CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
第三個參數,InputArray類型的kernel,腐蝕操作的內核。若爲NULL時,表示的是使用參考點位於中心3x3的核。我們一般使用函數 getStructuringElement配合這個參數的使用。getStructuringElement函數會返回指定形狀和尺寸的結構元素(內核矩陣)。(具體看上文中淺出部分dilate函數的第三個參數講解部分)
第四個參數,Point類型的anchor,錨的位置,其有默認值(-1,-1),表示錨位於單位(element)的中心,我們一般不用管它。
第五個參數,int類型的iterations,迭代使用erode()函數的次數,默認值爲1。
第六個參數,int類型的borderType,用於推斷圖像外部像素的某種邊界模式。注意它有默認值BORDER_DEFAULT。
第七個參數,const Scalar&類型的borderValue,當邊界爲常數時的邊界值,有默認值morphologyDefaultBorderValue(),一般我們不用去管他。需要用到它時,可以看官方文檔中的createMorphologyFilter()函數得到更詳細的解釋。

腐蝕和膨脹是相反的操作,膨脹希望高亮區域越來越大,而腐蝕希望高亮區域越來越小,看數學表達式就可以理解這一點:

四、看源碼理解

//腐蝕操作函數
void cv::erode( InputArray src, OutputArray dst, InputArray kernel,
                Point anchor, int iterations,
                int borderType, const Scalar& borderValue )
{
    //直接調用,設置標誌爲MORPH_ERODE
    morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}

//膨脹操作函數
void cv::dilate( InputArray src, OutputArray dst, InputArray kernel,
                 Point anchor, int iterations,
                 int borderType, const Scalar& borderValue )
{
    //設置標誌爲MORPH_DILATE
    morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}

這是隻是設置好標誌後調用高層函數來實現功能。

五、試用

void usage_dilate()
{
    Mat  image = imread("./smimage/1.jpg");
    //show the src image
    imshow("SRC", image);
    //get the kernel 
    Mat ele = getStructuringElement(MORPH_RECT, Size(3,3));
    Mat res;
    dilate(image, res, ele);
    //show the res image
    imshow("RES", res);
    waitKey(0);
}
void usage_erode()
{
    Mat src = imread("./smimage/1.jpg");
    //get the kernel
    Mat ele = getStructuringElement(MORPH_RECT, Size(5, 5));
    Mat res;
    erode(src, res, ele);
    //show the image
    imshow("SRC", src);
    imshow("RES", res);
    waitKey(0);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章