1、源码
https://github.com/opencv/opencv/blob/master/modules/imgproc/src/contours.cpp
\opencv\build\include\opencv2\imgproc\imgproc.hpp
/** @brief Finds contours in a binary image. The function retrieves contours from the binary image using the algorithm @cite Suzuki85 . The contours are a useful tool for shape analysis and object detection and recognition. See squares.cpp in the OpenCV sample directory. @note Since opencv 3.2 source image is not modified by this function. @param image Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as binary . You can use #compare, #inRange, #threshold , #adaptiveThreshold, #Canny, and others to create a binary image out of a grayscale or color one. If mode equals to #RETR_CCOMP or #RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1). @param contours Detected contours. Each contour is stored as a vector of points (e.g. std::vector<std::vector<cv::Point> >). @param hierarchy Optional output vector (e.g. std::vector<cv::Vec4i>), containing information about the image topology. It has as many elements as the number of contours. For each i-th contour contours[i], the elements hierarchy[i][0] , hierarchy[i][1] , hierarchy[i][2] , and hierarchy[i][3] are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative. @param mode Contour retrieval mode, see #RetrievalModes @param method Contour approximation method, see #ContourApproximationModes @param offset Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context. */ CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point()); /** @overload */ CV_EXPORTS void findContours( InputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset = Point());
2、论文
根据opencv官方文档,OpenCV: Contours Hierarchy,采用的是:
Suzuki, S. and Abe, K.,Topological Structural Analysis of Digitized Binary Images by Border Following. CVGIP 30 1, pp 32-46 (1985)
说明:openCv的contours是分级的,其寻边理论依据(方式)参考suzuki的论文《Topological structural analysis of digitized binary images by border following》。
http://pdf-s3.xuebalib.com:1262/1ftg5E69C3uX.pdf
3、Contour 的寻边模式 Mode
openCV通过一个矩阵来管理等级,矩阵的元素表示方法是:[Next, Previous, First_Child, Parent]
RETR_LIST:列出所有的边,没有父子层级之分(全部边缘都为1级)。
在这种模式下,这8条边建立的等级关系为
[ 1, -1, -1, -1], [ 2, 0, -1, -1], [ 3, 1, -1, -1], [ 4, 2, -1, -1],
[ 5, 3, -1, -1], [ 6, 4, -1, -1], [ 7, 5, -1, -1], [-1, 6, -1, -1]
例如边“0”,其同等级的Next是边“1”,前一个不存在(-1),没有First_Child, Parent,这两个参数也都设为-1,所以第0个元素是
[1,-1,-1,-1];边“1”,其同等级的Next是边“2”,前一个边是“0”,没有First_Child, Parent,两个-1,所以第1个元素是[2,0,-1,-1];依次类推。
RETR_EXTERNAL:列出最外面的边(如物体的外边框),不管被包围的内环或边(如物体的孔洞)。
RETR_CCOMP:只取2个层级的边,如下图,只把边(粉红色)分为两个层(绿色),标记为绿色的(1)顶层和(2)次层。
上面图中,这9条边建立的等级关系为
[ 3, -1, 1, -1], [ 2, -1, -1, 0], [-1, 1, -1, 0], [ 5, 0, 4, -1], [-1, -1, -1, 3],
[ 7, 3, 6, -1], [-1, -1, -1, 5], [ 8, 5, -1, -1], [-1, 7, -1, -1]
例如第"0"边,其相邻的Next是边"3", Previous不存在(-1),First-child=边"1",Parent不存在(-1),所以其相应的元素为
[3, -1, 1, -1],其余元素依此规则类推。
RETR_TREE:返回所有的边及层级关系,
这9条边建立的等级关系为
[ 7, -1, 1, -1], [-1, -1, 2, 0], [-1, -1, 3, 1], [-1, -1, 4, 2], [-1, -1, 5, 3],
[ 6, -1, -1, 4], [-1, 5, -1, 4], [ 8, 0, -1, -1], [-1, 7, -1, -1]
---