我们常常需要对一幅图像做轮廓的查找,尤其是在做物体的检测与识别的时候。
一般的步骤就是先使用canny方法来得到一幅图像的边缘情况。然后使用findContours方法来得到边缘图像的轮廓。最后使用drawContours方法来绘制轮廓。
canny我们都很清楚它的使用方法了。
这里简单地说一下findContours和drawContours
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
image是canny(或者其他方法)处理好的8位单通道图像。findContours方法把非零的值都认为是1。零值认为是0。即image认为是二值图像。
contours就是输出的轮廓。vector<vector<Point> > contours;是一组点的向量。
hierarchy是描述轮廓信息的信息。vector<Vec4i> hierarchy;每个contours[i]对应hierarchy[i][0]到hierarchy[i][3]这四个值。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是轮廓检索的模式。有CV_RETR_EXTERNAL, CV_RETR_LIST, CV_RETR_CCOMP, CV_RETR_TREE这四种,一般我们使用最后一种。
method是轮廓估算的方法。有CV_CHAIN_APPROX_NONE, CV_CHAIN_APPROX_SIMPLE, CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS,一般我们使用CV_CHAIN_APPROX_SIMPLE
offset是偏移量,这里不叙。保持默认。
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
有了findContours的说明,这个drawContours就比较简单了。看下面的代码,一目了然。
1 Mat canny_output; 2 vector<vector<Point> > contours; 3 vector<Vec4i> hierarchy; 4 5 /// Detect edges using canny 6 Canny( src_gray, canny_output, thresh, thresh*2, 3 ); 7 /// Find contours 8 findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); 9 10 /// Draw contours 11 Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); 12 for( int i = 0; i< contours.size(); i++ ) 13 { 14 Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); 15 drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); 16 } 17 18 /// Show in a window 19 namedWindow( "Contours", CV_WINDOW_AUTOSIZE ); 20 imshow( "Contours", drawing );