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