1 #include <opencv2/imgproc/imgproc.hpp>
2 #include <opencv2/highgui/highgui.hpp>
3 #include <iostream>
4
5 using namespace cv;
6 using namespace std;
7
help()8 static void help()
9 {
10 cout << "\nThis program demostrates iterative construction of\n"
11 "delaunay triangulation and voronoi tesselation.\n"
12 "It draws a random set of points in an image and then delaunay triangulates them.\n"
13 "Usage: \n"
14 "./delaunay \n"
15 "\nThis program builds the traingulation 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,char **)106 int main( int, char** )
107 {
108 help();
109
110 Scalar active_facet_color(0, 0, 255), delaunay_color(255,255,255);
111 Rect rect(0, 0, 600, 600);
112
113 Subdiv2D subdiv(rect);
114 Mat img(rect.size(), CV_8UC3);
115
116 img = Scalar::all(0);
117 string win = "Delaunay Demo";
118 imshow(win, img);
119
120 for( int i = 0; i < 200; i++ )
121 {
122 Point2f fp( (float)(rand()%(rect.width-10)+5),
123 (float)(rand()%(rect.height-10)+5));
124
125 locate_point( img, subdiv, fp, active_facet_color );
126 imshow( win, img );
127
128 if( waitKey( 100 ) >= 0 )
129 break;
130
131 subdiv.insert(fp);
132
133 img = Scalar::all(0);
134 draw_subdiv( img, subdiv, delaunay_color );
135 imshow( win, img );
136
137 if( waitKey( 100 ) >= 0 )
138 break;
139 }
140
141 img = Scalar::all(0);
142 paint_voronoi( img, subdiv );
143 imshow( win, img );
144
145 waitKey(0);
146
147 return 0;
148 }
149