1 /********************************************************************************
2 *
3 *
4 *  This program is demonstration for ellipse fitting. Program finds
5 *  contours and approximate it by ellipses.
6 *
7 *  Trackbar specify threshold parametr.
8 *
9 *  White lines is contours. Red lines is fitting ellipses.
10 *
11 *
12 *  Autor:  Denis Burenkov.
13 *
14 *
15 *
16 ********************************************************************************/
17 #include "opencv2/imgproc/imgproc.hpp"
18 #include "opencv2/imgcodecs.hpp"
19 #include "opencv2/highgui/highgui.hpp"
20 #include <iostream>
21 using namespace cv;
22 using namespace std;
23 
24 // static void help()
25 // {
26 //     cout <<
27 //             "\nThis program is demonstration for ellipse fitting. The program finds\n"
28 //             "contours and approximate it by ellipses.\n"
29 //             "Call:\n"
30 //             "./fitellipse [image_name -- Default ../data/stuff.jpg]\n" << endl;
31 // }
32 
33 int sliderPos = 70;
34 
35 Mat image;
36 
37 void processImage(int, void*);
38 
main(int argc,char ** argv)39 int main( int argc, char** argv )
40 {
41     const char* filename = argc == 2 ? argv[1] : (char*)"../data/stuff.jpg";
42     image = imread(filename, 0);
43     if( image.empty() )
44     {
45         cout << "Couldn't open image " << filename << "\nUsage: fitellipse <image_name>\n";
46         return 0;
47     }
48 
49     imshow("source", image);
50     namedWindow("result", 1);
51 
52     // Create toolbars. HighGUI use.
53     createTrackbar( "threshold", "result", &sliderPos, 255, processImage );
54     processImage(0, 0);
55 
56     // Wait for a key stroke; the same function arranges events processing
57     waitKey();
58     return 0;
59 }
60 
61 // Define trackbar callback functon. This function find contours,
62 // draw it and approximate it by ellipses.
processImage(int,void *)63 void processImage(int /*h*/, void*)
64 {
65     vector<vector<Point> > contours;
66     Mat bimage = image >= sliderPos;
67 
68     findContours(bimage, contours, RETR_LIST, CHAIN_APPROX_NONE);
69 
70     Mat cimage = Mat::zeros(bimage.size(), CV_8UC3);
71 
72     for(size_t i = 0; i < contours.size(); i++)
73     {
74         size_t count = contours[i].size();
75         if( count < 6 )
76             continue;
77 
78         Mat pointsf;
79         Mat(contours[i]).convertTo(pointsf, CV_32F);
80         RotatedRect box = fitEllipse(pointsf);
81 
82         if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 )
83             continue;
84         drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8);
85 
86         ellipse(cimage, box, Scalar(0,0,255), 1, LINE_AA);
87         ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0,255,255), 1, LINE_AA);
88         Point2f vtx[4];
89         box.points(vtx);
90         for( int j = 0; j < 4; j++ )
91             line(cimage, vtx[j], vtx[(j+1)%4], Scalar(0,255,0), 1, LINE_AA);
92     }
93 
94     imshow("result", cimage);
95 }
96