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 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 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 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 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 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 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