参考链接:
http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html
http://blog.csdn.net/shouhuxianjian/article/details/42686395
http://blog.csdn.net/shaoxiaohu1/article/details/40272875
http://mobile.51cto.com/aengine-435442.htm
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
Parameters:
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. The function modifies the image while extracting the contours.
contours – Detected contours. Each contour is stored as a vector of points.
hierarchy – Optional output vector, 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] , hiearchy[i][1] , hiearchy[i][2] , and hiearchy[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.
mode – Contour retrieval mode .
CV_RETR_EXTERNAL retrieves only the extreme outer contours. It sets hierarchy[i][2]=hierarchy[i][3]=-1 for all the contours.
CV_RETR_LIST retrieves all of the contours without establishing any hierarchical relationships.
CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy.
At the top level, there are external boundaries of the components.
At the second level, there are boundaries of the holes.
If there is another contour inside a hole of a connected component, it is still put at the top level.
CV_RETR_TREE retrieves all of the contours and reconstructs a full hierarchy of nested contours. This full hierarchy is built and shown in the OpenCV contours.c demo.
method – Contour approximation method .
CV_CHAIN_APPROX_NONE stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is, max(abs(x1-x2),abs(y2-y1))==1.
CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS applies one of the flavors of the Teh-Chin chain approximation algorithm. See [TehChin89] for details.
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.
The function retrieves contours from the binary image using the algorithm [Suzuki85]. The contours are a useful tool for shape analysis and object detection and recognition. See squares.c in the OpenCV sample directory.
Note: Source image is modified by this function. Also, the function does not take into account 1-pixel border of the image (it’s filled with 0’s and used for neighbor analysis in the algorithm), therefore the contours touching the image border will be clipped.
Note:
An example using the findContour functionality can be found at opencv_source_code/samples/cpp/contours2.cpp
An example using findContours to clean up a background segmentation result at opencv_source_code/samples/cpp/segment_objects.cpp
疑问1:findContours函数使用几邻域做bwlabel?实际测试是满足8领域的。
1 Mat skin_8; 2 vector<vector<cv::Point> > contours ; 3 findContours(skin_8, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 4 5 vector<cv::Rect> boxes; 6 //获取满足条件的连通域 7 for(size_t i = 0; i < contours.size(); i++) 8 { 9 //double area = cv::contourArea(contours[i]); 10 cv::Rect rect = cv::boundingRect(contours[i]); 11 //cout << "rect[" << i << "]---[" << rect.x << ", " << rect.y << ", " << rect.width << ", " << rect.height << "]" << endl; 12 if ( !((rect.width < 40) || (rect.height < 40) || (rect.height/rect.width > 2.8) || (rect.height/rect.width < 0.5)) ) 13 { 14 boxes.push_back(rect); 15 } 16 }