123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include <opencv2/imgproc.hpp>
- #include <opencv2/highgui.hpp>
- #include <iostream>
- using namespace cv;
- using namespace std;
- static void help(char** argv)
- {
- cout << "\nThis program demonstrates iterative construction of\n"
- "delaunay triangulation and voronoi tessellation.\n"
- "It draws a random set of points in an image and then delaunay triangulates them.\n"
- "Usage: \n";
- cout << argv[0];
- cout << "\n\nThis program builds the triangulation interactively, you may stop this process by\n"
- "hitting any key.\n";
- }
- static void draw_subdiv_point( Mat& img, Point2f fp, Scalar color )
- {
- circle( img, fp, 3, color, FILLED, LINE_8, 0 );
- }
- static void draw_subdiv( Mat& img, Subdiv2D& subdiv, Scalar delaunay_color )
- {
- #if 1
- vector<Vec6f> triangleList;
- subdiv.getTriangleList(triangleList);
- vector<Point> pt(3);
- for( size_t i = 0; i < triangleList.size(); i++ )
- {
- Vec6f t = triangleList[i];
- pt[0] = Point(cvRound(t[0]), cvRound(t[1]));
- pt[1] = Point(cvRound(t[2]), cvRound(t[3]));
- pt[2] = Point(cvRound(t[4]), cvRound(t[5]));
- line(img, pt[0], pt[1], delaunay_color, 1, LINE_AA, 0);
- line(img, pt[1], pt[2], delaunay_color, 1, LINE_AA, 0);
- line(img, pt[2], pt[0], delaunay_color, 1, LINE_AA, 0);
- }
- #else
- vector<Vec4f> edgeList;
- subdiv.getEdgeList(edgeList);
- for( size_t i = 0; i < edgeList.size(); i++ )
- {
- Vec4f e = edgeList[i];
- Point pt0 = Point(cvRound(e[0]), cvRound(e[1]));
- Point pt1 = Point(cvRound(e[2]), cvRound(e[3]));
- line(img, pt0, pt1, delaunay_color, 1, LINE_AA, 0);
- }
- #endif
- }
- static void locate_point( Mat& img, Subdiv2D& subdiv, Point2f fp, Scalar active_color )
- {
- int e0=0, vertex=0;
- subdiv.locate(fp, e0, vertex);
- if( e0 > 0 )
- {
- int e = e0;
- do
- {
- Point2f org, dst;
- if( subdiv.edgeOrg(e, &org) > 0 && subdiv.edgeDst(e, &dst) > 0 )
- line( img, org, dst, active_color, 3, LINE_AA, 0 );
- e = subdiv.getEdge(e, Subdiv2D::NEXT_AROUND_LEFT);
- }
- while( e != e0 );
- }
- draw_subdiv_point( img, fp, active_color );
- }
- static void paint_voronoi( Mat& img, Subdiv2D& subdiv )
- {
- vector<vector<Point2f> > facets;
- vector<Point2f> centers;
- subdiv.getVoronoiFacetList(vector<int>(), facets, centers);
- vector<Point> ifacet;
- vector<vector<Point> > ifacets(1);
- for( size_t i = 0; i < facets.size(); i++ )
- {
- ifacet.resize(facets[i].size());
- for( size_t j = 0; j < facets[i].size(); j++ )
- ifacet[j] = facets[i][j];
- Scalar color;
- color[0] = rand() & 255;
- color[1] = rand() & 255;
- color[2] = rand() & 255;
- fillConvexPoly(img, ifacet, color, 8, 0);
- ifacets[0] = ifacet;
- polylines(img, ifacets, true, Scalar(), 1, LINE_AA, 0);
- circle(img, centers[i], 3, Scalar(), FILLED, LINE_AA, 0);
- }
- }
- int main( int argc, char** argv )
- {
- cv::CommandLineParser parser(argc, argv, "{help h||}");
- if (parser.has("help"))
- {
- help(argv);
- return 0;
- }
- Scalar active_facet_color(0, 0, 255), delaunay_color(255,255,255);
- Rect rect(0, 0, 600, 600);
- Subdiv2D subdiv(rect);
- Mat img(rect.size(), CV_8UC3);
- img = Scalar::all(0);
- string win = "Delaunay Demo";
- imshow(win, img);
- for( int i = 0; i < 200; i++ )
- {
- Point2f fp( (float)(rand()%(rect.width-10)+5),
- (float)(rand()%(rect.height-10)+5));
- locate_point( img, subdiv, fp, active_facet_color );
- imshow( win, img );
- if( waitKey( 100 ) >= 0 )
- break;
- subdiv.insert(fp);
- img = Scalar::all(0);
- draw_subdiv( img, subdiv, delaunay_color );
- imshow( win, img );
- if( waitKey( 100 ) >= 0 )
- break;
- }
- img = Scalar::all(0);
- paint_voronoi( img, subdiv );
- imshow( win, img );
- waitKey(0);
- return 0;
- }
|