TVP

# Python的换脸黑魔法了解一下？

dlib 实现了 Vahid Kazemi 和 Josephine Sullivan 所著论文《One Millisecond Face Alignment with an Ensemble of Regression Tree》一文中描述的算法。算法本身非常复杂，但是通过 dlib的接口实现它非常简单：

PREDICTOR_PATH = "/home/matt/dlib-18.16/shape_predictor_68_face_landmarks.dat"detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(PREDICTOR_PATH)def get_landmarks(im):

rects = detector(im, 1)

if len(rects) > 1:

raise TooManyFaces

if len(rects) == 0:

raise NoFacesreturn numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])

get_landmarks() 函数 以 numpy 数组的形式接收图像，并返回一个 68x2 的元素矩阵。矩阵的每一行与输入图像中特定特征点的 x，y 坐标相对应。

（地址：https://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2/download）

def transformation_from_points(points1, points2):

points1 = points1.astype(numpy.float64)

points2 = points2.astype(numpy.float64)

c1 = numpy.mean(points1, axis=0)

c2 = numpy.mean(points2, axis=0)

points1 -= c1

points2 -= c2

s1 = numpy.std(points1)

s2 = numpy.std(points2)

points1 /= s1

points2 /= s2

R = (U * Vt).T

return numpy.vstack([numpy.hstack(((s2 / s1) * R,

c2.T - (s2 / s1) * R * c1.T)),

numpy.matrix([0., 0., 1.])])

def warp_im(im, M, dshape):

output_im = numpy.zeros(dshape, dtype=im.dtype)

cv2.warpAffine(im,

M[:2],

(dshape[1], dshape[0]),

dst=output_im,

borderMode=cv2.BORDER_TRANSPARENT,

flags=cv2.WARP_INVERSE_MAP)return output_im

COLOUR_CORRECT_BLUR_FRAC = 0.6LEFT_EYE_POINTS = list(range(42, 48))RIGHT_EYE_POINTS = list(range(36, 42))def correct_colours(im1, im2, landmarks1):

numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) -

numpy.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))

blur_amount = int(blur_amount)

if blur_amount % 2 == 0:

blur_amount += 1

im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)

im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)

# Avoid divide-by-zero errors.

im2_blur += 128 * (im2_blur

return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /

im2_blur.astype(numpy.float64))

LEFT_EYE_POINTS = list(range(42, 48))RIGHT_EYE_POINTS = list(range(36, 42))LEFT_BROW_POINTS = list(range(22, 27))RIGHT_BROW_POINTS = list(range(17, 22))NOSE_POINTS = list(range(27, 35))MOUTH_POINTS = list(range(48, 61))OVERLAY_POINTS = [

LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,

NOSE_POINTS + MOUTH_POINTS,]FEATHER_AMOUNT = 11def draw_convex_hull(im, points, color):

points = cv2.convexHull(points)

cv2.fillConvexPoly(im, points, color=color)def get_face_mask(im, landmarks):

im = numpy.zeros(im.shape[:2], dtype=numpy.float64)

for group in OVERLAY_POINTS:

draw_convex_hull(im,

landmarks[group],

color=1)

im = numpy.array([im, im, im]).transpose((1, 2, 0))

im = (cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) > 0) * 1.0

im = cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0)

return immask = get_face_mask(im2, landmarks2)warped_mask = warp_im(mask, M, im1.shape)combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask],

axis=0)

output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask

https://github.com/matthewearl/faceswap/blob/master/faceswap.py

「十分AI」短视频课程最新上线

• 发表于:
• 原文链接http://kuaibao.qq.com/s/20180426A1LBFE00?refer=cp_1026
• 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号（企鹅号）传播渠道之一，根据《腾讯内容开放平台服务协议》转载发布内容。
• 如有侵权，请联系 cloudcommunity@tencent.com 删除。

2022-11-27

2022-11-27

2022-11-27

2022-11-27

2022-11-27

2022-11-27

2018-06-25

2022-11-27

2022-11-27

2022-11-27

2022-11-27

2022-11-27