Home | History | Annotate | Download | only in cpp
      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