您好,关于您提到的Python Dlib换脸,我可以为您提供以下代码参考:
```
import dlib
import cv2
import numpy as np
# 加载模型
predictor_path = 'shape_predictor_68_face_landmarks.dat'
face_swap = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
# 加载两张图片
img1 = cv2.imread('img1.jpg')
img2 = cv2.imread('img2.jpg')
# 人脸关键点检测与特征点提取
faces1 = face_swap(img1, 1)
faces2 = face_swap(img2, 1)
face1_points = []
face2_points = []
for face in faces1:
shape = predictor(img1, face)
for i in range(68):
face1_points.append((shape.part(i).x, shape.part(i).y))
for face in faces2:
shape = predictor(img2, face)
for i in range(68):
face2_points.append((shape.part(i).x, shape.part(i).y))
# 生成三角剖分
face_swap_triangulation = dlib.delaunay_triangulation(face1_points)
triangles = []
for i in range(face_swap_triangulation.shape[0]):
tr = []
for j in range(3):
tr.append(face_swap_triangulation[i][j])
triangles.append(tr)
# 仿射变换调整图片
def apply_affine_transform(src, src_tri, dst_tri, size):
warp_mat = cv2.getAffineTransform(np.float32(src_tri), np.float32(dst_tri))
dst = cv2.warpAffine(src, warp_mat, (size[0], size[1]), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
return dst
# 泊松融合
def apply_mask(src, mask):
thresh = cv2.threshold(mask, 1, 255, cv2.THRESH_BINARY)[1]
mask = cv2.merge([thresh, thresh, thresh])
return cv2.bitwise_and(src, mask)
def apply_poisson(src, src_tri, dst_tri, dst, size):
warp_mat = cv2.getAffineTransform(np.float32(src_tri), np.float32(dst_tri))
src_warp = cv2.warpAffine(src, warp_mat, (size[0], size[1]), None, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
mask = np.zeros((size[1], size[0], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(dst_tri), (1.0, 1.0, 1.0), 16, 0)
mask = (mask * 255).astype(np.uint8)
cv2.imshow("mask", mask)
cv2.waitKey(1000)
r = cv2.boundingRect(np.float32([dst_tri]))
center = ((r[0]+int(r[2]/2), r[1]+int(r[3]/2)))
output = cv2.seamlessClone(np.uint8(src_warp), dst, mask, center, cv2.NORMAL_CLONE)
return output
# 换脸主程序入口
def face_swap_image(img1, img2):
faces1 = face_swap(img1, 1)
faces2 = face_swap(img2, 1)
face1_points = []
face2_points = []
for face in faces1:
shape = predictor(img1, face)
for i in range(68):
face1_points.append((shape.part(i).x, shape.part(i).y))
for face in faces2:
shape = predictor(img2, face)
for i in range(68):
face2_points.append((shape.part(i).x, shape.part(i).y))
if len(faces1) > 0 and len(faces2) > 0:
# 调整图片大小,使得两张图片尺寸一致
height, width, channels = img2.shape
img1_resized = cv2.resize(img1, (width, height))
# 人脸关键点检测与特征点提取
faces1 = face_swap(img1_resized, 1)
faces2 = face_swap(img2, 1)
face1_points = []
face2_points = []
for face in faces1:
shape = predictor(img1_resized, face)
for i in range(68):
face1_points.append((shape.part(i).x, shape.part(i).y))
for face in faces2:
shape = predictor(img2, face)
for i in range(68):
face2_points.append((shape.part(i).x, shape.part(i).y))
# 生成三角剖分
img2_new_face = np.zeros_like(img2)
for triangle in triangles:
# 获取面部特征点序号
x1, y1 = face1_points[triangle[0]]
x2, y2 = face1_points[triangle[1]]
x3, y3 = face1_points[triangle[2]]
src = np.float32([[x1, y1], [x2, y2], [x3, y3]])
# 获取新脸的面部特征点
x1, y1 = face2_points[triangle[0]]
x2, y2 = face2_points[triangle[1]]
x3, y3 = face2_points[triangle[2]]
dst = np.float32([[x1, y1], [x2, y2], [x3, y3]])
# 仿射变换调整图片
warped_triangle = apply_affine_transform(img1_resized, src, dst, (width, height))
# 泊松融合
mask = np.zeros_like(img2_new_face)
cv2.fillConvexPoly(mask, np.int32(dst), (255, 255, 255))
warped_triangle_masked = apply_mask(warped_triangle, mask)
img2_new_face = cv2.add(img2_new_face, warped_triangle_masked)
# 边缘融合
r = cv2.boundingRect(np.float32([face2_points]))
center = ((r[0]+int(r[2]/2), r[1]+int(r[3]/2)))
output = apply_poisson(img2_new_face, face2_points, np.array(triangles), img2, img2.shape[0:2])
# 返回融合后的图片
return output
else:
# 未检测到人脸,直接返回原图
return img2
img1 = cv2.imread('img1.jpg')
img2 = cv2.imread('img2.jpg')
output = face_swap_image(img1, img2)
cv2.imshow("Face Swap Output", output)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
这段代码使用了Python的Dlib库进行人脸关键点检测与特征点提取,并对两张图片进行三角剖分、仿射变换调整和泊松融合等操作,实现了换脸效果。
希望能够对您有所帮助,如果您还有任何问题,请随时询问我。