points = []
# 添加每一组
points.append((x, y))
2. 使用矩形(rect)定义要分区的空间。如果在上一步中定义的点是在图像上定义的,则此矩形可以是(0,0,width,height)。否则,您可以选择一个包含点的矩形。
img = cv2.imread("image.jpg");
size = img.shape
rect = (0, 0, size[1], size[0])
3.使用上一步中获得的矩形创建Subdiv2D的实例
subdiv = cv2.Subdiv2D(rect);
import cv2
import numpy as np
import random
# 检查一个点是否在矩形内
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
# 绘制一个点
def draw_point(img, p, color ) :
cv2.circle( img, p, 2, color, cv2.cv.CV_FILLED, cv2.CV_AA, 0 )
# 绘制 delaunay 三角剖分
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)
# 绘制 voronoi 图
def draw_voronoi(img, subdiv) :
( facets, centers) = subdiv.getVoronoiFacetList([])
for i in xrange(0,len(facets)) :
ifacet_arr = []
for f in facets :
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[0], centers[1]), 3, (0, 0, 0), cv2.cv.CV_FILLED, cv2.CV_AA, 0)
if __name__ == '__main__':
win_delaunay = "Delaunay Triangulation"
win_voronoi = "Voronoi Diagram"
# 当绘制三角形剖分时打开动画画板
animate = True
# 定义绘制颜色
delaunay_color = (255,255,255)
points_color = (0, 0, 255)
img = cv2.imread("image.jpg");
img_orig = img.copy();
# 创建用于Subdiv2D 的矩形
size = img.shape
rect = (0, 0, size[1], size[0])
# 创建Subdiv2D 实例
subdiv = cv2.Subdiv2D(rect);
points = [];
# 从 text 文件中读取点
with open("points.txt") as file :
for line in file :
x, y = line.split()
points.append((int(x), int(y)))
# 将点依次插入subdiv中
for p in points :
subdiv.insert(p)
# 展示动画画板
if animate :
img_copy = img_orig.copy()
draw_delaunay( img_copy, subdiv, (255, 255, 255) );
cv2.imshow(win_delaunay, img_copy)
cv2.waitKey(100)
# 绘制delaunay 三角剖分
draw_delaunay( img, subdiv, (255, 255, 255) );
for p in points :
draw_point(img, p, (0,0,255))
# 为Voronoi 图分配空间
img_voronoi = np.zeros(img.shape, dtype = img.dtype)
# 绘制 Voronoi 图
draw_voronoi(img_voronoi,subdiv)
cv2.imshow(win_delaunay,img)
cv2.imshow(win_voronoi,img_voronoi)
cv2.waitKey(0)
得到的结果就是和图1的中间图和右图一样,如果想要看Dlaunay三角剖分的动态过程可以访问这里,或者自己运行上述的代码
openCV【实践系列】5——使用OpenCV进行Delaunay三角剖分
https://bbs.easyaiforum.cn/thread-704-1-1.html
(出处: 易学智能)