e1895def0c650712ef2e8bddcaf107d5a4724a45
[opencv] / samples / c / fitellipse.c
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 #ifdef _CH_
18 #pragma package <opencv>
19 #endif
20
21 #ifndef _EiC
22 #include "cv.h"
23 #include "highgui.h"
24 #endif
25
26 int slider_pos = 70;
27
28 // Load the source image. HighGUI use.
29 IplImage *image02 = 0, *image03 = 0, *image04 = 0;
30
31 void process_image(int h);
32
33 int main( int argc, char** argv )
34 {
35     const char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
36     
37     // load image and force it to be grayscale
38     if( (image03 = cvLoadImage(filename, 0)) == 0 )
39         return -1;
40
41     // Create the destination images
42     image02 = cvCloneImage( image03 );
43     image04 = cvCloneImage( image03 );
44
45     // Create windows.
46     cvNamedWindow("Source", 1);
47     cvNamedWindow("Result", 1);
48
49     // Show the image.
50     cvShowImage("Source", image03);
51
52     // Create toolbars. HighGUI use.
53     cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image );
54
55     process_image(0);
56
57     // Wait for a key stroke; the same function arranges events processing                
58     cvWaitKey(0);
59     cvReleaseImage(&image02);
60     cvReleaseImage(&image03);
61
62     cvDestroyWindow("Source");
63     cvDestroyWindow("Result");
64
65     return 0;
66 }
67
68 // Define trackbar callback functon. This function find contours,
69 // draw it and approximate it by ellipses.
70 void process_image(int h)
71 {
72     CvMemStorage* stor;
73     CvSeq* cont;
74     CvBox2D32f* box;
75     CvPoint* PointArray;
76     CvPoint2D32f* PointArray2D32f;
77     
78     // Create dynamic structure and sequence.
79     stor = cvCreateMemStorage(0);
80     cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
81     
82     // Threshold the source image. This needful for cvFindContours().
83     cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY );
84     
85     // Find all contours.
86     cvFindContours( image02, stor, &cont, sizeof(CvContour), 
87                     CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
88     
89     // Clear images. IPL use.
90     cvZero(image02);
91     cvZero(image04);
92     
93     // This cycle draw all contours and approximate it by ellipses.
94     for(;cont;cont = cont->h_next)
95     {   
96         int i; // Indicator of cycle.
97         int count = cont->total; // This is number point in contour
98         CvPoint center;
99         CvSize size;
100         
101         // Number point must be more than or equal to 6 (for cvFitEllipse_32f).        
102         if( count < 6 )
103             continue;
104         
105         // Alloc memory for contour point set.    
106         PointArray = (CvPoint*)malloc( count*sizeof(CvPoint) );
107         PointArray2D32f= (CvPoint2D32f*)malloc( count*sizeof(CvPoint2D32f) );
108         
109         // Alloc memory for ellipse data.
110         box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));
111         
112         // Get contour point set.
113         cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ);
114         
115         // Convert CvPoint set to CvBox2D32f set.
116         for(i=0; i<count; i++)
117         {
118             PointArray2D32f[i].x = (float)PointArray[i].x;
119             PointArray2D32f[i].y = (float)PointArray[i].y;
120         }
121         
122         // Fits ellipse to current contour.
123         cvFitEllipse(PointArray2D32f, count, box);
124         
125         // Draw current contour.
126         cvDrawContours(image04,cont,CV_RGB(255,255,255),CV_RGB(255,255,255),0,1,8,cvPoint(0,0));
127         
128         // Convert ellipse data from float to integer representation.
129         center.x = cvRound(box->center.x);
130         center.y = cvRound(box->center.y);
131         size.width = cvRound(box->size.width*0.5);
132         size.height = cvRound(box->size.height*0.5);
133         box->angle = -box->angle;
134         
135         // Draw ellipse.
136         cvEllipse(image04, center, size,
137                   box->angle, 0, 360,
138                   CV_RGB(0,0,255), 1, CV_AA, 0);
139         
140         // Free memory.          
141         free(PointArray);
142         free(PointArray2D32f);
143         free(box);
144     }
145     
146     // Show image. HighGUI use.
147     cvShowImage( "Result", image04 );
148 }
149
150 #ifdef _EiC
151 main(1,"fitellipse.c");
152 #endif