delaunay2.cpp 3.83 KB
Newer Older
1 2
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
3 4 5 6 7 8 9
#include <iostream>

using namespace cv;
using namespace std;

static void help()
{
10
    cout << "\nThis program demostrates iterative construction of\n"
11 12 13 14 15 16 17 18 19 20
           "delaunay triangulation and voronoi tesselation.\n"
           "It draws a random set of points in an image and then delaunay triangulates them.\n"
           "Usage: \n"
           "./delaunay \n"
           "\nThis program builds the traingulation interactively, you may stop this process by\n"
           "hitting any key.\n";
}

static void draw_subdiv_point( Mat& img, Point2f fp, Scalar color )
{
21
    circle( img, fp, 3, color, FILLED, LINE_8, 0 );
22 23 24 25
}

static void draw_subdiv( Mat& img, Subdiv2D& subdiv, Scalar delaunay_color )
{
26
#if 1
27 28 29
    vector<Vec6f> triangleList;
    subdiv.getTriangleList(triangleList);
    vector<Point> pt(3);
30

31 32 33 34 35 36
    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]));
37 38 39
        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);
40
    }
41 42 43 44 45 46 47 48
#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]));
49
        line(img, pt0, pt1, delaunay_color, 1, LINE_AA, 0);
50 51
    }
#endif
52 53 54 55 56
}

static void locate_point( Mat& img, Subdiv2D& subdiv, Point2f fp, Scalar active_color )
{
    int e0=0, vertex=0;
57

58
    subdiv.locate(fp, e0, vertex);
59

60 61 62 63 64 65 66
    if( e0 > 0 )
    {
        int e = e0;
        do
        {
            Point2f org, dst;
            if( subdiv.edgeOrg(e, &org) > 0 && subdiv.edgeDst(e, &dst) > 0 )
67
                line( img, org, dst, active_color, 3, LINE_AA, 0 );
68

69 70 71 72
            e = subdiv.getEdge(e, Subdiv2D::NEXT_AROUND_LEFT);
        }
        while( e != e0 );
    }
73

74 75 76 77
    draw_subdiv_point( img, fp, active_color );
}


78
static void paint_voronoi( Mat& img, Subdiv2D& subdiv )
79 80
{
    vector<vector<Point2f> > facets;
81 82
    vector<Point2f> centers;
    subdiv.getVoronoiFacetList(vector<int>(), facets, centers);
83

84 85
    vector<Point> ifacet;
    vector<vector<Point> > ifacets(1);
86

87 88 89 90 91
    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];
92

93
        Scalar color;
94 95 96
        color[0] = rand() & 255;
        color[1] = rand() & 255;
        color[2] = rand() & 255;
97
        fillConvexPoly(img, ifacet, color, 8, 0);
98

99
        ifacets[0] = ifacet;
100 101
        polylines(img, ifacets, true, Scalar(), 1, LINE_AA, 0);
        circle(img, centers[i], 3, Scalar(), FILLED, LINE_AA, 0);
102 103 104 105 106 107 108
    }
}


int main( int, char** )
{
    help();
109

110 111
    Scalar active_facet_color(0, 0, 255), delaunay_color(255,255,255);
    Rect rect(0, 0, 600, 600);
112

113 114
    Subdiv2D subdiv(rect);
    Mat img(rect.size(), CV_8UC3);
115

116 117 118
    img = Scalar::all(0);
    string win = "Delaunay Demo";
    imshow(win, img);
119

120 121 122 123
    for( int i = 0; i < 200; i++ )
    {
        Point2f fp( (float)(rand()%(rect.width-10)+5),
                    (float)(rand()%(rect.height-10)+5));
124

125 126
        locate_point( img, subdiv, fp, active_facet_color );
        imshow( win, img );
127

128 129
        if( waitKey( 100 ) >= 0 )
            break;
130

131
        subdiv.insert(fp);
132

133 134 135
        img = Scalar::all(0);
        draw_subdiv( img, subdiv, delaunay_color );
        imshow( win, img );
136

137 138 139
        if( waitKey( 100 ) >= 0 )
            break;
    }
140

141 142 143
    img = Scalar::all(0);
    paint_voronoi( img, subdiv );
    imshow( win, img );
144

145
    waitKey(0);
146

147 148
    return 0;
}