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