Skip to content

Commit

Permalink
Delaunay Triangulation & Voronoi Diagrams
Browse files Browse the repository at this point in the history
  • Loading branch information
spmallick committed Nov 5, 2015
1 parent ef4e8ea commit fabc858
Show file tree
Hide file tree
Showing 4 changed files with 344 additions and 0 deletions.
145 changes: 145 additions & 0 deletions Delaunay/delaunay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

// Draw a single point
static void draw_point( Mat& img, Point2f fp, Scalar color )
{
circle( img, fp, 2, color, CV_FILLED, CV_AA, 0 );
}

// Draw delaunay triangles
static void draw_delaunay( Mat& img, Subdiv2D& subdiv, Scalar delaunay_color )
{

vector<Vec6f> triangleList;
subdiv.getTriangleList(triangleList);
vector<Point> pt(3);
Size size = img.size();
Rect rect(0,0, size.width, size.height);

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]));

// Draw rectangles completely inside the image.
if ( rect.contains(pt[0]) && rect.contains(pt[1]) && rect.contains(pt[2]))
{
line(img, pt[0], pt[1], delaunay_color, 1, CV_AA, 0);
line(img, pt[1], pt[2], delaunay_color, 1, CV_AA, 0);
line(img, pt[2], pt[0], delaunay_color, 1, CV_AA, 0);
}
}
}

//Draw voronoi diagrams
static void draw_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, CV_AA, 0);
circle(img, centers[i], 3, Scalar(), CV_FILLED, CV_AA, 0);
}
}


int main( int argc, char** argv)
{

// Define window names
string win_delaunay = "Delaunay Triangulation";
string win_voronoi = "Voronoi Diagram";

// Turn on animation while drawing triangles
bool animate = true;

// Define colors for drawing.
Scalar delaunay_color(255,255,255), points_color(0, 0, 255);

// Read in the image.
Mat img = imread("obama.jpg");

// Keep a copy around
Mat img_orig = img.clone();

// Rectangle to be used with Subdiv2D
Size size = img.size();
Rect rect(0, 0, size.width, size.height);

// Create an instance of Subdiv2D
Subdiv2D subdiv(rect);

// Create a vector of points.
vector<Point2f> points;

// Read in the points from a text file
ifstream ifs("obama.txt");
int x, y;
while(ifs >> x >> y)
{
points.push_back(Point2f(x,y));
}

// Insert points into subdiv
for( vector<Point2f>::iterator it = points.begin(); it != points.end(); it++)
{
subdiv.insert(*it);
// Show animation
if (animate)
{
Mat img_copy = img_orig.clone();
// Draw delaunay triangles
draw_delaunay( img_copy, subdiv, delaunay_color );
imshow(win_delaunay, img_copy);
waitKey(100);
}

}

// Draw delaunay triangles
draw_delaunay( img, subdiv, delaunay_color );

// Draw points
for( vector<Point2f>::iterator it = points.begin(); it != points.end(); it++)
{
draw_point(img, *it, points_color);
}

// Allocate space for voronoi Diagram
Mat img_voronoi = Mat::zeros(img.rows, img.cols, CV_8UC3);

// Draw voronoi diagram
draw_voronoi( img_voronoi, subdiv );

// Show results.
imshow( win_delaunay, img);
imshow( win_voronoi, img_voronoi);
waitKey(0);

return 0;
}
131 changes: 131 additions & 0 deletions Delaunay/delaunay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/python

import cv2
import numpy as np
import random

# Check if a point is inside a rectangle
def rect_contains(rect, point) :
if point[0] < rect[0] :
return False
elif point[1] < rect[1] :
return False
elif point[0] > rect[2] :
return False
elif point[1] > rect[3] :
return False
return True

# Draw a point
def draw_point(img, p, color ) :
cv2.circle( img, p, 2, color, cv2.cv.CV_FILLED, cv2.CV_AA, 0 )


# Draw delaunay triangles
def draw_delaunay(img, subdiv, delaunay_color ) :

triangleList = subdiv.getTriangleList();
size = img.shape
r = (0, 0, size[1], size[0])

for t in triangleList :

pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])

if rect_contains(r, pt1) and rect_contains(r, pt2) and rect_contains(r, pt3) :

cv2.line(img, pt1, pt2, delaunay_color, 1, cv2.CV_AA, 0)
cv2.line(img, pt2, pt3, delaunay_color, 1, cv2.CV_AA, 0)
cv2.line(img, pt3, pt1, delaunay_color, 1, cv2.CV_AA, 0)


# Draw voronoi diagram
def draw_voronoi(img, subdiv) :

( facets, centers) = subdiv.getVoronoiFacetList([])

for i in xrange(0,len(facets)) :
ifacet_arr = []
for f in facets[i] :
ifacet_arr.append(f)

ifacet = np.array(ifacet_arr, np.int)
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

cv2.fillConvexPoly(img, ifacet, color, cv2.CV_AA, 0);
ifacets = np.array([ifacet])
cv2.polylines(img, ifacets, True, (0, 0, 0), 1, cv2.CV_AA, 0)
cv2.circle(img, (centers[i][0], centers[i][1]), 3, (0, 0, 0), cv2.cv.CV_FILLED, cv2.CV_AA, 0)


if __name__ == '__main__':

# Define window names
win_delaunay = "Delaunay Triangulation"
win_voronoi = "Voronoi Diagram"

# Turn on animation while drawing triangles
animate = True

# Define colors for drawing.
delaunay_color = (255,255,255)
points_color = (0, 0, 255)

# Read in the image.
img = cv2.imread("obama.jpg");

# Keep a copy around
img_orig = img.copy();

# Rectangle to be used with Subdiv2D
size = img.shape
rect = (0, 0, size[1], size[0])

# Create an instance of Subdiv2D
subdiv = cv2.Subdiv2D(rect);

# Create an array of points.
points = [];

# Read in the points from a text file
with open("obama.txt") as file :
for line in file :
x, y = line.split()
points.append((int(x), int(y)))

# Insert points into subdiv
for p in points :
subdiv.insert(p)

# Show animation
if animate :
img_copy = img_orig.copy()
# Draw delaunay triangles
draw_delaunay( img_copy, subdiv, (255, 255, 255) );
cv2.imshow(win_delaunay, img_copy)
cv2.waitKey(100)

# Draw delaunay triangles
draw_delaunay( img, subdiv, (255, 255, 255) );

# Draw points
for p in points :
draw_point(img, p, (0,0,255))

# Allocate space for voronoi Diagram
img_voronoi = np.zeros(img.shape, dtype = img.dtype)

# Draw voronoi diagram
draw_voronoi(img_voronoi,subdiv)

# Show results
cv2.imshow(win_delaunay,img)
cv2.imshow(win_voronoi,img_voronoi)
cv2.waitKey(0)





Binary file added Delaunay/obama.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions Delaunay/obama.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
207 242
210 269
214 297
220 322
229 349
243 373
261 394
282 412
308 416
334 408
356 388
374 367
388 344
397 319
403 291
405 263
408 235
221 241
232 225
250 219
270 219
289 223
320 222
339 216
358 215
375 220
387 233
304 240
304 259
304 277
304 296
281 311
292 312
303 314
315 310
326 307
243 247
254 240
266 239
276 245
266 247
254 249
332 243
343 236
356 236
367 242
356 245
344 245
263 346
278 341
293 336
303 340
315 335
331 338
348 342
332 353
318 360
305 362
294 361
279 356
270 347
293 347
304 348
316 345
342 343
316 345
304 348
294 347

0 comments on commit fabc858

Please sign in to comment.