opencv findContours函數


一、前言

  findContours函數的參數在眾多博客中都有詳細介紹,本篇隨筆主要針對個別函數參數做說明,並記錄相關的輸出參數的部分細節

二、函數介紹

  
  void findContours( InputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset = Point());  

  contours為獲取的輪廓信息,輪廓信息定義務必是vector<vector<Point>> 形式的

  hierarchy為層級關系,定義為vector<Vec4i>和Mat都可以。每個輪廓有四個層級信息,分別為:上一個輪廓序號、下一個輪廓序號、子輪廓序號、父輪廓序號

  mode 官方是“輪廓檢索算法的模式”,可以理解為獲取怎樣的層級信息

  method 輪廓近似模式

  offset

三、基本效果展示

  基本代碼:

    Mat img = imread("../contours.bmp",IMREAD_GRAYSCALE);
    imshow("source img",img);
    vector<vector<Point>> vContours;
    Mat mContourShow = Mat::zeros(img.size(),CV_8U);
    findContours(img,vContours,RETR_LIST,CHAIN_APPROX_NONE);
    drawContours(mContourShow,vContours,-1,Scalar(255));
    imshow("Contours",mContourShow);
    waitKey();

  代碼運行結果:      

     

四、個別參數的細節區分

  部分代碼:

1      vector<Vec4i> mHierarchy; 2 vector<vector<Point>> vContours; 3 Mat mContourShow = Mat::zeros(img.size(),CV_8UC3); 4 findContours(img,vContours,mHierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point(0,0)); 5 for(int i = 0; i<vContours.size(); i++){ 6 drawContours(mContourShow,vContours,i,Scalar(0,255,255),1,LINE_8); 7 putText(mContourShow,to_string(mHierarchy[i][0]).append(",").append(to_string(mHierarchy[i][1])),vContours[i][0],FONT_HERSHEY_SCRIPT_SIMPLEX,0.5,Scalar(255,255,0),1); 8 }

  4.1 mode層級信息

注:圖中我打的兩個數字標簽為層級關系的第一個數和第二個數

  mode分別為RETR_EXTERNAL(左上)、RETR_LIST(右上)、RETR_CCOMP(左下)、RETR_TREE(右下)時

的層級關系數組分別為

1,-1,-1,-1      1,-1,-1,-1          1,-1,-1,-1          7,-1,1,-1

-1,0,-1,-1      2,0,-1,-1           4,0,2,-1           6,-1,2,0

          3,1,-1,-1           3,-1,-1,1          -1,-1,3,1

          4,2,-1,-1           -1,2,-1,1          4,-1,-1,2

          5,3,-1,-1           7,1,5,-1           -1,3,5,2

          6,4,-1,-1           6,-1,-1,4          -1,-1,-1,4

 

          7,5,-1,-1           -1,5,-1,4          -1,1,-1,0

          -1,6,-1,-1          -1,4,-1,-1          -1,0,-1,-1

RETR_EXTERNAL模式是只找最外層的輪廓

RETR_LIST模式是找到所有的輪廓,但是不提供層級關系

RETR_CCOMP模式是找到所有輪廓,層級只有兩層(外輪廓和洞,洞里面再有輪廓按照外輪廓算,表現在層級關系上為:父輪廓無父輪廓,子輪廓無子輪廓),注意這里父輪廓只能指定一個子輪廓,但是多個子輪廓可以指定同一個父輪廓

RETR_TREE模式是以樹狀梳理所有輪廓的關系

RETR_FLOODFILL官網也沒有介紹,我這里用上面的圖得到的效果輪廓和層級結果也不好,這里暫時不深究了

PS:RETR_CCOMP模式可以對打了lable的圖片(比如通過connectcomponent函數或者watershed函數獲得的結果)進行輪廓識別

 

4.2 method擬合方法

此處我換了原圖,下列圖片從左到右依次為:原圖、CHAIN_APPROX_NONE方法、CHAIN_APPROX_SIMPLE方法、CHAIN_APPROX_TC89_L1方法、CHAIN_APPROX_TC89_KCOS方法(點集邊上的數字是點集個數)

 

CHAIN_APPROX_NONE是不做處理

CHAIN_APPROX_SIMPLE會將直線和對角線優化掉

CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS采用了近似算法

PS:如果需要真實的點集就使用前兩種方法。

 

五、其他

另外再補充幾點:

1、findContours找點集,對於“洞”的輪廓是4鄰域連續,對於外輪廓是16鄰域連續(如下圖所示),當用CHAIN_APPROX_SIMPLE簡化點時,矩形洞會簡化為8個點

2、所有邊界點集都是位於白色區域內的,不會因為它是洞就落在黑色區域上

 

                                                                                        代碼使用opencv版本:4.1.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM