diff --git a/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.markdown b/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.markdown index fef66fb665..56d886d89f 100644 --- a/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.markdown +++ b/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.markdown @@ -22,6 +22,49 @@ This tutorial code's is shown lines below. You can also download it from Explanation ----------- +The main function is rather simple, as follows from the comments we do the following: +-# Open the image, convert it into grayscale and blur it to get rid of the noise. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup +-# Create a window with header "Source" and display the source file in it. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow +-# Create a trackbar on the source_window and assign a callback function to it + In general callback functions are used to react to some kind of signal, in our + case it's trackbar's state change. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp taskbar +-# Explicit one-time call of `thresh_callback` is necessary to display + the "Contours" window simultaniously with the "Source" window. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp callback00 +-# Wait for user to close the windows. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp waitForIt + + +The callback function `thresh_callback` does all the interesting job. + + +-# Writes to `threshold_output` the threshold of the grayscale picture (you can check out about thresholding @ref tutorial_threshold "here"). + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp threshold +-# Finds contours and saves them to the vectors `contour` and `hierarchy`. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours +-# For every found contour we now apply approximation to polygons + with accuracy +-3 and stating that the curve must me closed. + + After that we find a bounding rect for every polygon and save it to `boundRect`. + + At last we find a minimum enclosing circle for every polygon and + save it to `center` and `radius` vectors. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework + +We found everything we need, all we have to do is to draw. + +-# Create new Mat of unsigned 8-bit chars, filled with zeros. + It will contain all the drawings we are going to make (rects and circles). + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat +-# For every contour: pick a random color, draw the contour, the bounding rectangle and + the minimal enclosing circle with it, + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour +-# Display the results: create a new window "Contours" and show everything we added to drawings on it. + @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings + Result ------ diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp index 29d75515cf..1e5585aa5f 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp @@ -25,22 +25,34 @@ void thresh_callback(int, void* ); */ int main( int, char** argv ) { - /// Load source image and convert it to gray + //![setup] + /// Load source image src = imread( argv[1], IMREAD_COLOR ); /// Convert image to gray and blur it cvtColor( src, src_gray, COLOR_BGR2GRAY ); blur( src_gray, src_gray, Size(3,3) ); + //![setup] + //![createWindow] /// Create Window const char* source_window = "Source"; namedWindow( source_window, WINDOW_AUTOSIZE ); imshow( source_window, src ); + //![createWindow] + //![taskbar] createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback ); + //![taskbar] + + //![callback00] thresh_callback( 0, 0 ); + //![callback00] + //![waitForIt] waitKey(0); + //![waitForIt] + return(0); } @@ -53,10 +65,15 @@ void thresh_callback(int, void* ) vector > contours; vector hierarchy; + //![threshold] /// Detect edges using Threshold threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY ); + //![threshold] + + //![findContours] /// Find contours findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) ); + //![findContours] /// Approximate contours to polygons + get bounding rects and circles vector > contours_poly( contours.size() ); @@ -64,24 +81,33 @@ void thresh_callback(int, void* ) vectorcenter( contours.size() ); vectorradius( contours.size() ); + //![allthework] for( size_t i = 0; i < contours.size(); i++ ) - { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); - boundRect[i] = boundingRect( Mat(contours_poly[i]) ); - minEnclosingCircle( contours_poly[i], center[i], radius[i] ); - } - - + { + approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); + boundRect[i] = boundingRect( Mat(contours_poly[i]) ); + minEnclosingCircle( contours_poly[i], center[i], radius[i] ); + } + //![allthework] + + //![zeroMat] /// Draw polygonal contour + bonding rects + circles Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); - for( size_t i = 0; i< contours.size(); i++ ) - { - Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector(), 0, Point() ); - rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); - circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); - } + //![zeroMat] + //![forContour] + for( size_t i = 0; i< contours.size(); i++ ) + { + Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); + drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector(), 0, Point() ); + rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); + circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); + } + //![forContour] + + //![showDrawings] /// Show in a window namedWindow( "Contours", WINDOW_AUTOSIZE ); imshow( "Contours", drawing ); + //![showDrawings] }