1 /**
2  * @function generalContours_demo1.cpp
3  * @brief Demo code to find contours in an image
4  * @author OpenCV team
5  */
6 
7 #include "opencv2/imgcodecs.hpp"
8 #include "opencv2/highgui.hpp"
9 #include "opencv2/imgproc.hpp"
10 #include <iostream>
11 
12 using namespace cv;
13 using namespace std;
14 
15 Mat src_gray;
16 int thresh = 100;
17 RNG rng(12345);
18 
19 /// Function header
20 void thresh_callback(int, void* );
21 
22 /**
23  * @function main
24  */
main(int argc,char ** argv)25 int main( int argc, char** argv )
26 {
27     //! [setup]
28     /// Load source image
29     CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );
30     Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );
31     if( src.empty() )
32     {
33         cout << "Could not open or find the image!\n" << endl;
34         cout << "usage: " << argv[0] << " <Input image>" << endl;
35         return -1;
36     }
37 
38     /// Convert image to gray and blur it
39     cvtColor( src, src_gray, COLOR_BGR2GRAY );
40     blur( src_gray, src_gray, Size(3,3) );
41     //! [setup]
42 
43     //! [createWindow]
44     /// Create Window
45     const char* source_window = "Source";
46     namedWindow( source_window );
47     imshow( source_window, src );
48     //! [createWindow]
49 
50     //! [trackbar]
51     const int max_thresh = 255;
52     createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
53     thresh_callback( 0, 0 );
54     //! [trackbar]
55 
56     waitKey();
57     return 0;
58 }
59 
60 /**
61  * @function thresh_callback
62  */
thresh_callback(int,void *)63 void thresh_callback(int, void* )
64 {
65     //! [Canny]
66     /// Detect edges using Canny
67     Mat canny_output;
68     Canny( src_gray, canny_output, thresh, thresh*2 );
69     //! [Canny]
70 
71     //! [findContours]
72     /// Find contours
73     vector<vector<Point> > contours;
74     findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
75     //! [findContours]
76 
77     //! [allthework]
78     /// Approximate contours to polygons + get bounding rects and circles
79     vector<vector<Point> > contours_poly( contours.size() );
80     vector<Rect> boundRect( contours.size() );
81     vector<Point2f>centers( contours.size() );
82     vector<float>radius( contours.size() );
83 
84     for( size_t i = 0; i < contours.size(); i++ )
85     {
86         approxPolyDP( contours[i], contours_poly[i], 3, true );
87         boundRect[i] = boundingRect( contours_poly[i] );
88         minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
89     }
90     //! [allthework]
91 
92     //! [zeroMat]
93     Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
94     //! [zeroMat]
95 
96     //! [forContour]
97     /// Draw polygonal contour + bonding rects + circles
98     for( size_t i = 0; i< contours.size(); i++ )
99     {
100         Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
101         drawContours( drawing, contours_poly, (int)i, color );
102         rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 );
103         circle( drawing, centers[i], (int)radius[i], color, 2 );
104     }
105     //! [forContour]
106 
107     //! [showDrawings]
108     /// Show in a window
109     imshow( "Contours", drawing );
110     //! [showDrawings]
111 }
112