1. 程式人生 > >OpenCV中findcontours函式hierarchy輪廓層級詳解

OpenCV中findcontours函式hierarchy輪廓層級詳解

最近在查閱OpenCV輪廓處理函式方面時,我發現有部分文章對findcontours函式中輪廓層級提取的描述有錯誤,特寫一篇有關輪廓提取方面的文章(僅僅介紹容易出錯的hierarchy層級輪廓)。

函式原型為:findContours(image,contours,hierarchy,mode,method,Point());注意函式過載!

以下,利用mode=CV_RETR_TREE,進行hierarchy的介紹。

CV_RETR_TREE方法為檢測所有輪廓,並且建立所有的繼承(包含)關係(hierarchy輪廓繼承可以大顯身手!)。

對於每一個輪廓,hierarchy都包含4個整型資料,分別表示:後一個輪廓的序號

前一個輪廓的序號子輪廓的序號父輪廓的序號

特別注意,上述的含義的不能弄反了!

在理解層級關係前,需要對資料結構有一定的瞭解。

例如下圖(將樹結構和輪廓級聯絡在一起),A和B為同級,可以認為B是A的後一個輪廓,A是B的前一個輪廓;C和D為A的子樹,E和F為B的子樹,可以認為C和D為A的子輪廓,A為C和D的父輪廓。

為了更加直觀,可以利用實際的影象進一步說明輪廓層級的關係,例如以下的源圖,一共有4個輪廓,序號分別為0 1 2 3

特別地,序號在程式中findcontours函式會自動標記,也是輪廓檢索的序號,n個輪廓其檢索序號從 0 到 n-1 。

經分析,0號輪廓沒有同級輪廓,有兩個子級輪廓1和3,沒有父級輪廓,所以其輪廓繼承關係向量hierarchy為[-1 -1 1 -1],-1表示無對應的關係,1表示0號輪廓的一個子輪廓的序號為1號;

同樣地,1號輪廓有同級輪廓3(認為是後一個輪廓,那麼無前一個輪廓),也有子級輪廓2,也有父級輪廓0,所以其輪廓繼承關係向量hierarchy為[3 -1 2 0];

同樣地,2號輪廓沒有同級輪廓,也沒有子級輪廓,但是有父級輪廓1,所以其輪廓繼承關係向量hierarchy為[-1 -1 -1 1];

同樣地,3號輪廓有同級輪廓(其前一個輪廓為1,無後一個輪廓),沒有子級輪廓,但是有父級輪廓0,所以其輪廓繼承關係向量hierarchy為[-1 1 -1 0]。

以上的輪廓層級關係,可以用樹結構表示如下:

C++版部分測試程式碼如下:

--------------------------

    cv::Mat img = cv::imread("E:\\test.bmp", 0);//需要bmp圖

    cv::vector<cv::vector<cv::Point2i>> contours;
    cv::vector<cv::Vec4i> hierarchy;
    cv::findContours(img, contours, hierarchy,CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point());

---------------------------

利用輪廓處理函式,後續可以很方便地對影象進行連通域處理、特徵擬合和特徵識別等。