preliminary version of a multi-level findcontours
[profile/ivi/opencv.git] / samples / c / contours.c
1 #include <opencv2/imgproc/imgproc_c.h>
2 #include "opencv2/highgui/highgui.hpp"
3 #include <stdio.h>
4 void help()
5 {
6         printf("\nThis program creates an image to demonstrate the use of the \"c\" contour\n"
7                         "functions: cvFindContours() and cvApproxPoly() along with the storage\n"
8                         "functions cvCreateMemStorage() and cvDrawContours().\n"
9                         "It also shows the use of a trackbar to control contour retrieval.\n"
10                         "\n"
11             "Usage :\n"
12                         "./contours\n");
13 }
14
15 #define w 500
16 int levels = 3;
17 CvSeq* contours = 0;
18
19 void on_trackbar(int pos)
20 {
21     IplImage* cnt_img = cvCreateImage( cvSize(w,w), 8, 3 );
22     CvSeq* _contours = contours;
23     int _levels = levels - 3;
24     if( _levels <= 0 ) // get to the nearest face to make it look more funny
25         _contours = _contours->h_next->h_next->h_next;
26     cvZero( cnt_img );
27     cvDrawContours( cnt_img, _contours, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels, 3, CV_AA, cvPoint(0,0) );
28     cvShowImage( "contours", cnt_img );
29     cvReleaseImage( &cnt_img );
30 }
31
32 static void findCComp( IplImage* img )
33 {
34     int x, y, cidx = 1;
35     IplImage* mask = cvCreateImage( cvSize(img->width+2, img->height+2), 8, 1 );
36     cvZero(mask);
37     cvRectangle( mask, cvPoint(0, 0), cvPoint(mask->width-1, mask->height-1),
38                  cvScalarAll(1), 1, 8, 0 );
39     
40     for( y = 0; y < img->height; y++ )
41         for( x = 0; x < img->width; x++ )
42         {
43             if( CV_IMAGE_ELEM(mask, uchar, y+1, x+1) != 0 )
44                 continue;
45             cvFloodFill(img, cvPoint(x,y), cvScalarAll(cidx),
46                         cvScalarAll(0), cvScalarAll(0), 0, 4, mask);
47             cidx++;
48         }
49 }
50
51
52 int main( int argc, char** argv )
53 {
54     int i, j;
55     CvMemStorage* storage = cvCreateMemStorage(0);
56     IplImage* img = cvCreateImage( cvSize(w,w), 8, 1 );
57     IplImage* img32f = cvCreateImage( cvSize(w,w), IPL_DEPTH_32F, 1 );
58     IplImage* img32s = cvCreateImage( cvSize(w,w), IPL_DEPTH_32S, 1 );
59     IplImage* img3 = cvCreateImage( cvSize(w,w), 8, 3 );
60     help();
61     cvZero( img );
62
63     for( i=0; i < 6; i++ )
64     {
65         int dx = (i%2)*250 - 30;
66         int dy = (i/2)*150;
67         CvScalar white = cvRealScalar(255);
68         CvScalar black = cvRealScalar(0);
69
70         if( i == 0 )
71         {
72             for( j = 0; j <= 10; j++ )
73             {
74                 double angle = (j+5)*CV_PI/21;
75                 cvLine(img, cvPoint(cvRound(dx+100+j*10-80*cos(angle)),
76                     cvRound(dy+100-90*sin(angle))),
77                     cvPoint(cvRound(dx+100+j*10-30*cos(angle)),
78                     cvRound(dy+100-30*sin(angle))), white, 3, 8, 0);
79             }
80         }
81
82         cvEllipse( img, cvPoint(dx+150, dy+100), cvSize(100,70), 0, 0, 360, white, -1, 8, 0 );
83         cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
84         cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
85         cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
86         cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
87         cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
88         cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
89         cvEllipse( img, cvPoint(dx+150, dy+100), cvSize(10,5), 0, 0, 360, black, -1, 8, 0 );
90         cvEllipse( img, cvPoint(dx+150, dy+150), cvSize(40,10), 0, 0, 360, black, -1, 8, 0 );
91         cvEllipse( img, cvPoint(dx+27, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
92         cvEllipse( img, cvPoint(dx+273, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
93     }
94
95     cvNamedWindow( "image", 1 );
96     cvShowImage( "image", img );
97     cvConvert( img, img32f );
98     findCComp( img32f );
99     cvConvert( img32f, img32s );
100
101     cvFindContours( img32s, storage, &contours, sizeof(CvContour),
102                     CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
103     
104     //cvFindContours( img, storage, &contours, sizeof(CvContour),
105     //                CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
106     
107     
108     {
109     const char* attrs[] = {"recursive", "1", 0};
110     cvSave("contours.xml", contours, 0, 0, cvAttrList(attrs, 0));
111     contours = (CvSeq*)cvLoad("contours.xml", storage, 0, 0);
112     }
113
114     // comment this out if you do not want approximation
115     contours = cvApproxPoly( contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );
116
117     cvNamedWindow( "contours", 1 );
118     cvCreateTrackbar( "levels+3", "contours", &levels, 7, on_trackbar );
119
120     {
121         CvRNG rng = cvRNG(-1);
122         
123         CvSeq* tcontours = contours;
124         cvCvtColor( img, img3, CV_GRAY2BGR );
125         while( tcontours->h_next )
126             tcontours = tcontours->h_next;
127
128         for( ; tcontours != 0; tcontours = tcontours->h_prev )
129         {
130             CvScalar color;
131             color.val[0] = cvRandInt(&rng) % 256;
132             color.val[1] = cvRandInt(&rng) % 256;
133             color.val[2] = cvRandInt(&rng) % 256;
134             color.val[3] = cvRandInt(&rng) % 256;
135             cvDrawContours(img3, tcontours, color, color, 0, -1, 8, cvPoint(0,0));
136             if( tcontours->v_next )
137             {
138                 color.val[0] = cvRandInt(&rng) % 256;
139                 color.val[1] = cvRandInt(&rng) % 256;
140                 color.val[2] = cvRandInt(&rng) % 256;
141                 color.val[3] = cvRandInt(&rng) % 256;
142                 cvDrawContours(img3, tcontours->v_next, color, color, 1, -1, 8, cvPoint(0,0));
143             }
144         }
145         
146     }
147     
148     cvShowImage( "colored", img3 );
149     on_trackbar(0);
150     cvWaitKey(0);
151     cvReleaseMemStorage( &storage );
152     cvReleaseImage( &img );
153     cvReleaseImage( &img32f );
154     cvReleaseImage( &img32s );
155     cvReleaseImage( &img3 );
156     
157     return 0;
158 }
159
160 #ifdef _EiC
161 main(1,"");
162 #endif