Update to 2.0.0 tree from current Fremantle build
[opencv] / samples / swig_python / delaunay.py
1 #!/usr/bin/python
2 """
3 the script demostrates iterative construction of
4 delaunay triangulation and voronoi tesselation
5
6 Original Author (C version): ?
7 Converted to Python by: Roman Stanchak
8 """
9 from opencv.cv import *
10 from opencv.highgui import *
11 from random import random,randint
12
13 def draw_subdiv_point( img, fp, color ):
14     cvCircle( img, cvPoint(cvRound(fp.x), cvRound(fp.y)), 3, color, CV_FILLED, 8, 0 );
15
16
17
18 def draw_subdiv_edge( img, edge, color ):
19     org_pt = cvSubdiv2DEdgeOrg(edge);
20     dst_pt = cvSubdiv2DEdgeDst(edge);
21
22     if org_pt and dst_pt :
23     
24         org = org_pt.pt;
25         dst = dst_pt.pt;
26
27         iorg = cvPoint( cvRound( org.x ), cvRound( org.y ));
28         idst = cvPoint( cvRound( dst.x ), cvRound( dst.y ));
29
30         cvLine( img, iorg, idst, color, 1, CV_AA, 0 );
31
32
33 def draw_subdiv( img, subdiv, delaunay_color, voronoi_color ):
34     
35     total = subdiv.edges.total;
36     elem_size = subdiv.edges.elem_size;
37
38     for edge in subdiv.edges:
39         edge_rot = cvSubdiv2DRotateEdge( edge, 1 )
40
41         if( CV_IS_SET_ELEM( edge )):
42             draw_subdiv_edge( img, edge_rot, voronoi_color );
43             draw_subdiv_edge( img, edge, delaunay_color );
44
45
46 def locate_point( subdiv, fp, img, active_color ):
47
48     [res, e0, p] = cvSubdiv2DLocate( subdiv, fp );
49
50     if e0:
51         e = e0
52         while True:
53             draw_subdiv_edge( img, e, active_color );
54             e = cvSubdiv2DGetEdge(e,CV_NEXT_AROUND_LEFT);
55             if e == e0:
56                 break
57
58     draw_subdiv_point( img, fp, active_color );
59
60
61 def draw_subdiv_facet( img, edge ):
62
63     t = edge;
64     count = 0;
65
66     # count number of edges in facet
67     while count == 0 or t != edge:
68         count+=1
69         t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
70
71     buf = []
72
73     # gather points
74     t = edge;
75     for i in range(count):
76         assert t>4
77         pt = cvSubdiv2DEdgeOrg( t );
78         if not pt: 
79             break;
80         buf.append( cvPoint( cvRound(pt.pt.x), cvRound(pt.pt.y) ) );
81         t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
82
83     if( len(buf)==count ):
84         pt = cvSubdiv2DEdgeDst( cvSubdiv2DRotateEdge( edge, 1 ));
85         cvFillConvexPoly( img, buf, CV_RGB(randint(0,255),randint(0,255),randint(0,255)), CV_AA, 0 );
86         cvPolyLine( img, [buf], 1, CV_RGB(0,0,0), 1, CV_AA, 0);
87         draw_subdiv_point( img, pt.pt, CV_RGB(0,0,0));
88
89 def paint_voronoi( subdiv, img ):
90     total = subdiv.edges.total;
91     elem_size = subdiv.edges.elem_size;
92
93     cvCalcSubdivVoronoi2D( subdiv );
94
95     for edge in subdiv.edges:
96
97         if( CV_IS_SET_ELEM( edge )):
98             # left
99             draw_subdiv_facet( img, cvSubdiv2DRotateEdge( edge, 1 ));
100
101             # right
102             draw_subdiv_facet( img, cvSubdiv2DRotateEdge( edge, 3 ));
103
104 if __name__ == '__main__':
105     win = "source";
106     rect = cvRect( 0, 0, 600, 600 );
107
108     active_facet_color = CV_RGB( 255, 0, 0 );
109     delaunay_color  = CV_RGB( 0,0,0);
110     voronoi_color = CV_RGB(0, 180, 0);
111     bkgnd_color = CV_RGB(255,255,255);
112
113     img = cvCreateImage( cvSize(rect.width,rect.height), 8, 3 );
114     cvSet( img, bkgnd_color );
115
116     cvNamedWindow( win, 1 );
117
118     storage = cvCreateMemStorage(0);
119     subdiv = cvCreateSubdivDelaunay2D( rect, storage );
120
121     print "Delaunay triangulation will be build now interactively."
122     print "To stop the process, press any key\n";
123
124     for i in range(200):
125         fp = cvPoint2D32f( random()*(rect.width-10)+5, random()*(rect.height-10)+5 )
126
127         locate_point( subdiv, fp, img, active_facet_color );
128         cvShowImage( win, img );
129
130         if( cvWaitKey( 100 ) >= 0 ):
131             break;
132
133         cvSubdivDelaunay2DInsert( subdiv, fp );
134         cvCalcSubdivVoronoi2D( subdiv );
135         cvSet( img, bkgnd_color );
136         draw_subdiv( img, subdiv, delaunay_color, voronoi_color );
137         cvShowImage( win, img );
138
139         if( cvWaitKey( 100 ) >= 0 ):
140             break;
141     
142
143     cvSet( img, bkgnd_color );
144     paint_voronoi( subdiv, img );
145     cvShowImage( win, img );
146
147     cvWaitKey(0);
148
149     cvDestroyWindow( win );