本文主要是介绍delaunay和voronoi图 人脸三角剖分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
先获取人脸68个特征点坐标,其中使用了官方的预训练模型shape_predictor_68_face_landmarks.dat:
import dlib
import cv2predictor_path = "shape_predictor_68_face_landmarks.dat"
png_path = "face.jpg"txt_path = "points.txt"
f = open(txt_path, 'w+')# 与人脸检测相同,使用dlib自带的frontal_face_detector作为人脸检测器
detector = dlib.get_frontal_face_detector()
# 相撞
# 使用官方提供的模型构建特征提取器
predicator = dlib.shape_predictor(predictor_path)
win = dlib.image_window()
img1 = cv2.imread(png_path)dets = detector(img1, 1)
print("Number of faces detected : {}".format(len(dets)))
for k, d in enumerate(dets):print("Detection {} left:{} Top: {} Right {} Bottom {}".format(k, d.left(), d.top(), d.right(), d.bottom()))lanmarks = [[p.x, p.y] for p in predicator(img1, d).parts()]for idx, point in enumerate(lanmarks):f.write(str(point[0]))f.write("\t")f.write(str(point[1]))f.write('\n')
实现人脸三角剖分:
# 日期: 2023/11/2 23:04
import cv2
import numpy as np
import random# 检查点是否在矩形框内
def rect_contains(rect, point):if point[0] < rect[0]:return Falseelif point[1] < rect[1]:return Falseelif point[0] > rect[2]:return Falseelif point[1] > rect[3]:return Falsereturn True# 画点
def draw_point(img, p, color):cv2.circle(img, p, 2, color)# 绘制德劳内三角形
def draw_delaunay(img, subdiv, delaunay_color):trangleList = subdiv.getTriangleList() # 获取Delaunay三角形的列表size = img.shaper = (0, 0, size[1], size[0])for t in trangleList:pt1 = (int(t[0]), int(t[1]))pt2 = (int(t[2]), int(t[3]))pt3 = (int(t[4]), int(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.line(img, pt2, pt3, delaunay_color, 1)cv2.line(img, pt3, pt1, delaunay_color, 1)# Draw voronoi diagram
def draw_voronoi(img: object, subdiv: object) -> object:(facets, centers) = subdiv.getVoronoiFacetList([]) # 获取Voronoi构面的列表# 对于每个voronoi多边形for i in range(0, len(facets)):ifacet_arr = []# 得到每个多边形的顶点for f in facets[i]:ifacet_arr.append(f)ifacet = np.array(ifacet_arr, dtype=np.int32)# 随机颜色color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))# 填充颜色cv2.fillConvexPoly(img, ifacet, color) # 图像、多边形顶点、颜色vertex = np.array([ifacet])cv2.polylines(img, vertex, True, (0, 0, 0), 1) # 绘制多边形,参数包括图像、多边形的点、线条是否闭合、颜色和线条宽度cv2.circle(img, (centers[i][0], centers[i][1]), 3, (0, 0, 0)) # 绘制圆,参数包括图像、中心点、半径、颜色if __name__ == '__main__':# 定义窗口名称win_delaunary = "Delaunay Triangulation"win_voronoi = "Voronoi Diagram"# 在画三角形的时候开启动画animate = True# 定义画的颜色delaunary_color = (255, 255, 255)points_color = (0, 0, 255)# 读入图片img_path = "face.jpg"img = cv2.imread(img_path)# 复制img_orig = img.copy()# 矩形框用于Subdiv2Dsize = img.shape # h, w, channel# x,y,w,hrect = (0, 0, size[1], size[0])# 创建一个Subdiv2D的实例subdiv = cv2.Subdiv2D(rect)# 创建点的列表points = []# 从文档中读取点的坐标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_delaunary, img_copy)cv2.waitKey(100)# 绘制德劳内三角形draw_delaunay(img, subdiv, (255, 255, 255))# 绘制点for p in points:draw_point(img, p, (0, 0, 255))# 为沃罗诺伊图分配空间img_voronoi = np.zeros(img.shape, dtype=img.dtype)# 绘制沃罗诺伊图draw_voronoi(img_voronoi, subdiv)# 展示结果cv2.imshow(win_delaunary, img)cv2.imshow(win_voronoi, img_voronoi)cv2.waitKey(0)
这篇关于delaunay和voronoi图 人脸三角剖分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!