侵蝕、膨脹(erode、dilate)

形態學主要用於二值化後的影像,根據使用者的目的,用來凸顯影像的形狀特徵,像邊界和連通區域等,同時像細化、像素化、修剪毛刺等技術也常用於圖像的預處理和後處理,形態學操作的結果除了影像本身,也和結構元素的形狀有關,結構元素和空間域操作的濾波概念類似,如以下即為一個3×3的結構元素,我們可以自行決定大小和形狀,在實際的使用上,是以奇數的矩形如3×3、5×5、7×7較常見。

morphology


我們這邊介紹型態學裡最基本的侵蝕和膨脹,侵蝕顧名思義就是消融物體的邊界,如果物體大於結構元素,侵蝕的結果是讓物體瘦一圈,而這一圈的寬度是由結構元素大小決定的,如果物體小於結構元素,則侵蝕後物體會消失,如果物體之間有小於結構元素的細小連通,侵蝕後會分裂成兩個物體,OpenCV也提供erode()函式執行蝕刻。

對於集合I和H,假設使用H對I進行侵蝕,記作:erode

操作上我們把H當作結構元素,H在整個影像平面上移動,當H的原點平移到物體上某位置時,如果此時H能完全包覆於物體I中,就紀錄物體此點位置,所有這樣的像素位置集合,即為侵蝕後的物體,H的原點位置使用者自行設計,通常都為中央。

假設H長、寬皆為d,對物體(I)進行侵蝕,侵蝕後物體(I)四周皆縮水d/2的寬度。

erode

假設H長、寬皆為d,物體高度d,侵蝕後物體成為一條線。

erode

OpenCV侵蝕

erode(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)

  • src:輸入圖,可以多通道,深度可為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F。
  • dst:輸出圖,和輸入圖尺寸、型態相同。
  • kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大侵蝕效果越明顯。
  • anchor:原點位置,預設為結構元素的中央。
  • iterations:執行次數,預設為1次,執行越多次侵蝕效果越明顯。

膨脹為擴大物體的邊界,而擴大的寬度是由結構元素大小決定的,如果物體間有小於結構元素的細小間隙,膨脹能讓原本分開的物體連接起來,OpenCV提供dilate()函式進行膨脹。

對於集合I和H,假設使用H對I進行膨脹,記作:dilate

操作上我們把H當作結構元素,H在整個影像平面上移動,當H的原點平移到物體上某位置時,紀錄此時H包含的所有像素位置,所有這樣的像素位置集合,即為膨脹後的物體,H的原點位置使用者自行設計,通常都為中央。

假設H長、寬皆為d,對物體(I)進行膨脹,膨脹後物體(I)四周皆擴大d/2的寬度。

enter image description here

假設H長、寬皆為d,物體高度d,膨脹後物體(I)四周皆擴大d/2的寬度。

enter image description here

OpenCV膨脹

dilate(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)

  • src:輸入圖,可以多通道,深度可為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F。
  • dst:輸出圖,和輸入圖尺寸、型態相同。
  • kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大膨脹效果越明顯。
  • anchor:原點位置,預設為結構元素的中央。
  • iterations:執行次數,預設為1次,執行越多次膨脹效果越明顯。

OpenCV 得結構元素

OpenCV提供getStructuringElement()讓我們得到要進行侵蝕或膨脹的模板

Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))

  • shape:模板形狀,有MORPH_RECT、MORPH_ELLIPSE、MORPH_CROSS三種可選。
  • ksize:模板尺寸。

以下程式碼示範erode()和dilate()的使用,模板參數可輸入Mat(),此時會用3×3的矩形模板,也可以用getStructuringElement()來得到想要的大小和形狀的模板,我們可以看出二值化的圖形,在進行侵蝕或膨脹後,影像變化的樣子:

#include <cstdio>
#include <opencv2/opencv.hpp>
using namespace cv;

int main(){
    Mat src = imread("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    Mat src2;
    threshold(src,src2,120,255,THRESH_BINARY);
    Mat dst1;
    Mat dst2;
    Mat dst3;
    erode(src2, dst1, Mat());
    dilate(src2, dst2, Mat());
    Mat erodeStruct = getStructuringElement(MORPH_RECT,Size(5,5));
    erode(src2, dst3, erodeStruct);
    imshow("origin", src2);
    imshow("erode", dst1);
    imshow("dilate", dst2);
    imshow("erode2", dst3);
    waitKey(0);

    return 0;
}

型態學

型態學

型態學

型態學

回到首頁

回到OpenCV教學


參考資料:

OpenCV 教程