我们基本思路是从识别出特征点出发,连接这些特征点形成一个一个的三角形,然后用相同点连接三角形进行替换来实现换脸的效果。
细分三角形
subdiv = cv2.Subdiv2D(rect)
subdiv.insert(lamdmarks_points)
triangles = subdiv.getTriangleList()
triangles = np.array(triangles,np.int32)
返回指定点所属三角形相关信息
返回指定点所属三角形相关信息
通过 Subdiv2D 对矩形进行细分
pt 指定点
edge 指定点所属三角形最初的边ID
vertex 指定点所属三角形最初的頂点ID
绘制三角形
我们通过将这些点依次连接起来获取一系列三角形
图
for triangle_index in indexes_triangles:
# print(triangle)
pt1 = lamdmarks_points[triangle_index[0]]
pt2 = lamdmarks_points[triangle_index[1]]
pt3 = lamdmarks_points[triangle_index[2]]
cv2.line(img2,pt1,pt2,(0,0,255),2)
cv2.line(img2,pt3,pt2,(0,0,255),2)
cv2.line(img2,pt1,pt3,(0,0,255),2)
face 2_triangle_lines.png
face 2_with_landmark.png
tr1_pt1 = lamdmarks_points[triangle_index[0]]
tr1_pt2 = lamdmarks_points[triangle_index[1]]
tr1_pt3 = lamdmarks_points[triangle_index[2]]
triangle1 = np.array([tr1_pt1,tr1_pt2,tr1_pt3],np.int32)
triangle1 = np.array([tr1_pt1,tr1_pt2,tr1_pt3],np.int32)
rect1 = cv2.boundingRect(triangle1)
(x,y,w,h) = rect1
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
基本思路是这样我们先将这些小三角形切分成小块,然后通过mask(遮罩)获取三角形。
图 cropped triangle 1.png cropped triangle 2.png
添加遮罩提取三角形的图像
cropped_triangle = img[y:y + h,x:x + w]
cropped_tr1_mask = np.zeros_like(cropped_triangle)
cropped_triangle = img[y:y + h,x:x + w]
cropped_tr1_mask = np.zeros_like(cropped_triangle)
points = np.array([[tr1_pt1[0] - x, tr1_pt1[1] - y],[tr1_pt2[0] - x, tr1_pt2[1] - y],[tr1_pt3[0] - x, tr1_pt3[1] - y]],np.int32)
cv2.fillConvexPoly(cropped_tr1_mask,points,255)
图
cropped_tr1_mask = np.zeros((h,w),np.uint8)
网友评论