delaunay2.cpp 4.0 KB

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