cv2 实现Delaunay三角剖分和Voronoi图(Delaunay Triangulation and Voronoi Diagram)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_39611196/article/details/85046647

本文主要介绍使用cv2模块实现Delaunay三角剖分和Voronoi图。

测试图片:

示例代码:

# 导入模块
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, 0)

# 绘制delaunay triangles
def draw_delaunay(img, subdiv, delaunary_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, delaunary_color, 1)
            cv2.line(img, pt2, pt3, delaunary_color, 1)
            cv2.line(img, pt3, pt1, delaunary_color, 1)

# 绘制 voroni diagram
def draw_voroni(img, subdiv):
    (facets, centers) = subdiv.getVoronoiFacetList([])
    
    for i in range(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, 0)
        ifacets = np.array([ifacet])
        cv2.polylines(img, ifacets, True, (0, 0, 0), 1)
        cv2.circle(img, (centers[i][0], centers[i][1]), 3, (0, 0, 0), 0)

# 定义窗口名称
win_delaunay = "Delaunay Triangulation"
win_voronoi = "Voronoi Diagram"

# 绘制三角形时打开动画
animats = True

# 定义绘制的颜色
delaunay_color = (255, 255, 255)
points_color = (0, 0, 255)

# 读取图片
img = cv2.imread('./obama.jpg')

# 复制图片
img_orig = img.copy()

# 与Subdiv2D一起使用的矩形
size = img.shape
rect = (0, 0, size[1], size[0])

# 创建Subdic2D的一个实例
subdiv = cv2.Subdiv2D(rect)

# 创建一个数组用于保存点
points = []


# 从文本文件读取点
with open('./obama.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)
        
        # 显示animation 
        if animats:
            img_copy = img_orig.copy()
            # 绘制delaunay triangle
            draw_delaunay(img_copy, subdiv, (255, 255, 255))
            
            # 显示结果
            # cv2.imshow(win_delaunay, img_copy)
            # cv2.waitKey(100)


# 绘制delaunay triangles
draw_delaunay( img, subdiv, (255, 255, 255) );

# 绘制点
for p in points :
    draw_point(img, p, (0,0,255))

# 为voronoi Diagram分配空间
img_voronoi = np.zeros(img.shape, dtype = img.dtype)

# 绘制voronoi diagram
draw_voroni(img_voronoi,subdiv)

# 保存结果
#保存结果
cv2.imwrite(win_delaunay + '.jpg', img)
cv2.imwrite(win_voronoi + '.jpg', img_voronoi)
# 显示结果
# cv2.imshow(win_delaunay,img)
# cv2.imshow(win_voronoi,img_voronoi)
# cv2.waitKey(0)    

结果:

Delaunay Triangulation:

Voronoi Diagram

猜你喜欢

转载自blog.csdn.net/github_39611196/article/details/85046647