1 #include <opencv2/imgproc.hpp>
2 #include <opencv2/highgui.hpp>
3 #include <iostream>
4 
5 using namespace cv;
6 using namespace std;
7 
help(char ** argv)8 static void help(char** argv)
9 {
10     cout << "\nThis program demonstrates iterative construction of\n"
11             "delaunay triangulation and voronoi tessellation.\n"
12             "It draws a random set of points in an image and then delaunay triangulates them.\n"
13             "Usage: \n";
14     cout << argv[0];
15     cout << "\n\nThis program builds the triangulation interactively, you may stop this process by\n"
16             "hitting any key.\n";
17 }
18 
draw_subdiv_point(Mat & img,Point2f fp,Scalar color)19 static void draw_subdiv_point( Mat& img, Point2f fp, Scalar color )
20 {
21     circle( img, fp, 3, color, FILLED, LINE_8, 0 );
22 }
23 
draw_subdiv(Mat & img,Subdiv2D & subdiv,Scalar delaunay_color)24 static void draw_subdiv( Mat& img, Subdiv2D& subdiv, Scalar delaunay_color )
25 {
26 #if 1
27     vector<Vec6f> triangleList;
28     subdiv.getTriangleList(triangleList);
29     vector<Point> pt(3);
30 
31     for( size_t i = 0; i < triangleList.size(); i++ )
32     {
33         Vec6f t = triangleList[i];
34         pt[0] = Point(cvRound(t[0]), cvRound(t[1]));
35         pt[1] = Point(cvRound(t[2]), cvRound(t[3]));
36         pt[2] = Point(cvRound(t[4]), cvRound(t[5]));
37         line(img, pt[0], pt[1], delaunay_color, 1, LINE_AA, 0);
38         line(img, pt[1], pt[2], delaunay_color, 1, LINE_AA, 0);
39         line(img, pt[2], pt[0], delaunay_color, 1, LINE_AA, 0);
40     }
41 #else
42     vector<Vec4f> edgeList;
43     subdiv.getEdgeList(edgeList);
44     for( size_t i = 0; i < edgeList.size(); i++ )
45     {
46         Vec4f e = edgeList[i];
47         Point pt0 = Point(cvRound(e[0]), cvRound(e[1]));
48         Point pt1 = Point(cvRound(e[2]), cvRound(e[3]));
49         line(img, pt0, pt1, delaunay_color, 1, LINE_AA, 0);
50     }
51 #endif
52 }
53 
locate_point(Mat & img,Subdiv2D & subdiv,Point2f fp,Scalar active_color)54 static void locate_point( Mat& img, Subdiv2D& subdiv, Point2f fp, Scalar active_color )
55 {
56     int e0=0, vertex=0;
57 
58     subdiv.locate(fp, e0, vertex);
59 
60     if( e0 > 0 )
61     {
62         int e = e0;
63         do
64         {
65             Point2f org, dst;
66             if( subdiv.edgeOrg(e, &org) > 0 && subdiv.edgeDst(e, &dst) > 0 )
67                 line( img, org, dst, active_color, 3, LINE_AA, 0 );
68 
69             e = subdiv.getEdge(e, Subdiv2D::NEXT_AROUND_LEFT);
70         }
71         while( e != e0 );
72     }
73 
74     draw_subdiv_point( img, fp, active_color );
75 }
76 
77 
paint_voronoi(Mat & img,Subdiv2D & subdiv)78 static void paint_voronoi( Mat& img, Subdiv2D& subdiv )
79 {
80     vector<vector<Point2f> > facets;
81     vector<Point2f> centers;
82     subdiv.getVoronoiFacetList(vector<int>(), facets, centers);
83 
84     vector<Point> ifacet;
85     vector<vector<Point> > ifacets(1);
86 
87     for( size_t i = 0; i < facets.size(); i++ )
88     {
89         ifacet.resize(facets[i].size());
90         for( size_t j = 0; j < facets[i].size(); j++ )
91             ifacet[j] = facets[i][j];
92 
93         Scalar color;
94         color[0] = rand() & 255;
95         color[1] = rand() & 255;
96         color[2] = rand() & 255;
97         fillConvexPoly(img, ifacet, color, 8, 0);
98 
99         ifacets[0] = ifacet;
100         polylines(img, ifacets, true, Scalar(), 1, LINE_AA, 0);
101         circle(img, centers[i], 3, Scalar(), FILLED, LINE_AA, 0);
102     }
103 }
104 
105 
main(int argc,char ** argv)106 int main( int argc, char** argv )
107 {
108     cv::CommandLineParser parser(argc, argv, "{help h||}");
109     if (parser.has("help"))
110     {
111         help(argv);
112         return 0;
113     }
114 
115     Scalar active_facet_color(0, 0, 255), delaunay_color(255,255,255);
116     Rect rect(0, 0, 600, 600);
117 
118     Subdiv2D subdiv(rect);
119     Mat img(rect.size(), CV_8UC3);
120 
121     img = Scalar::all(0);
122     string win = "Delaunay Demo";
123     imshow(win, img);
124 
125     for( int i = 0; i < 200; i++ )
126     {
127         Point2f fp( (float)(rand()%(rect.width-10)+5),
128                     (float)(rand()%(rect.height-10)+5));
129 
130         locate_point( img, subdiv, fp, active_facet_color );
131         imshow( win, img );
132 
133         if( waitKey( 100 ) >= 0 )
134             break;
135 
136         subdiv.insert(fp);
137 
138         img = Scalar::all(0);
139         draw_subdiv( img, subdiv, delaunay_color );
140         imshow( win, img );
141 
142         if( waitKey( 100 ) >= 0 )
143             break;
144     }
145 
146     img = Scalar::all(0);
147     paint_voronoi( img, subdiv );
148     imshow( win, img );
149 
150     waitKey(0);
151 
152     return 0;
153 }
154