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());
---------------------------
利用輪廓處理函式,後續可以很方便地對影象進行連通域處理、特徵擬合和特徵識別等。