龙空技术网

利用opencv模块简单的实现照片换脸术,Python就是这么牛逼

娇兮心有之 470

前言:

而今你们对“python安装cv2模块的方法”大概比较注意,朋友们都需要了解一些“python安装cv2模块的方法”的相关内容。那么小编在网络上收集了一些关于“python安装cv2模块的方法””的相关资讯,希望姐妹们能喜欢,朋友们快快来了解一下吧!

开发工具

相关模块:python-opencv模块;dlib模块;numpy模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

dlib据说用Anaconda装比较方便。年代太久远有些忘记了,我一直用原生的Python,忘了怎么装好的,似乎也挺方便的。之前的文章分享过一些编译好的whl文件,可以直接pip安装。

想要学习Python。关注小编头条号,私信【学习资料】,即可免费领取一整套系统的板Python学习教程!

原理简介

主要流程:

(1)利用dlib库检测并获取人脸特征点;

(2)通过一些简单的处理使得第二张人脸的眼睛、鼻子和嘴巴较好地“装”到第一张人脸上。

一些细节:

特征检测器:

用的dlib官方提供的预训练好的模型。

第二张图片的人脸特征需要对齐到第一张图片的人脸特征

具体实现方式详见相关文件中的源代码。

使用演示

修改SwapFace.py文件的图片路径为自己需要操作的图片路径:

然后在cmd窗口运行即可。

一些结果图:

(1)特朗普+奥巴马

(2)普及+安倍

(3)乔布斯+比尔盖茨

(4)莱布尼兹+牛顿

(5)爱因斯坦+薛定谔

完整代码

# 基于OpenCV的面部特征交换import numpy as npimport dlibimport cv2# 脸FACE_POINTS = list(range(17, 68))# 嘴巴MOUTH_POINTS = list(range(48, 61))# 右眉毛RIGHT_BROW_POINTS = list(range(17, 22))# 左眉毛LEFT_BROW_POINTS = list(range(22, 27))# 右眼RIGHT_EYE_POINTS = list(range(36, 42))# 左眼LEFT_EYE_POINTS = list(range(42, 48))# 鼻子NOSE_POINTS = list(range(27, 35))# 下巴JAW_POINTS = list(range(0, 17))detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')def GetLandmarks(img_path):	img = cv2.imread(img_path, cv2.IMREAD_COLOR)	rects = detector(img, 1)	if len(rects) > 1:		print('[Warning]: More than one face in picture, only choose one randomly...')		rects = rects[0]	elif len(rects) == 0:		print('[Error]: No face detected...')		return None	return img, np.matrix([[p.x, p.y] for p in predictor(img, rects[0]).parts()])# refer:# 	 TransferPoints(points1, points2):	points1 = points1.astype(np.float64)	points2 = points2.astype(np.float64)	c1 = np.mean(points1, axis=0)	c2 = np.mean(points2, axis=0)	points1 -= c1	points2 -= c2	s1 = np.std(points1)	s2 = np.std(points2)	points1 /= s1	points2 /= s2	# 奇异值分解	U, S, Vt = np.linalg.svd(points1.T * points2)	R = (U * Vt).T	return np.vstack([np.hstack(((s2/s1)*R, c2.T-(s2/s1)*R*c1.T)), np.matrix([0., 0., 1.])])def DrawConvexHull(img, points, color):	points = cv2.convexHull(points)	cv2.fillConvexPoly(img, points, color=color)def GetFaceMask(img, landmarks):	img = np.zeros(img.shape[:2], dtype=np.float64)	groups = [ 		LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,		NOSE_POINTS + MOUTH_POINTS,		]	for group in groups:		DrawConvexHull(img, landmarks[group], color=1)	img = np.array([img, img, img]).transpose((1, 2, 0))	img = (cv2.GaussianBlur(img, (11, 11), 0) > 0) * 1.0	img = cv2.GaussianBlur(img, (11, 11), 0)	return imgdef WarpImg(img, M, dshape):	output_img = np.zeros(dshape, dtype=img.dtype)	cv2.warpAffine(img,				 M[:2],				 (dshape[1], dshape[0]),				 dst=output_img,				 borderMode=cv2.BORDER_TRANSPARENT,				 flags=cv2.WARP_INVERSE_MAP)	return output_imgdef ModifyColor(img1, img2, landmarks1):	blur_amount = 0.6 * np.linalg.norm(np.mean(landmarks1[LEFT_EYE_POINTS], axis=0) - np.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))	blur_amount = int(blur_amount)	if blur_amount % 2 == 0:		blur_amount += 1	img1_blur = cv2.GaussianBlur(img1, (blur_amount, blur_amount), 0)	img2_blur = cv2.GaussianBlur(img2, (blur_amount, blur_amount), 0)	img2_blur += (128 * (img2_blur <= 1.0)).astype(img2_blur.dtype)	return (img2.astype(np.float64) * img1_blur.astype(np.float64) / img2_blur.astype(np.float64))def main(img1, img2):	ALIGN_POINTS = (LEFT_BROW_POINTS + RIGHT_EYE_POINTS + LEFT_EYE_POINTS + RIGHT_BROW_POINTS + NOSE_POINTS + MOUTH_POINTS)	img1, landmarks1 = GetLandmarks(img1)	img2, landmarks2 = GetLandmarks(img2)	M = TransferPoints(landmarks1[ALIGN_POINTS], landmarks2[ALIGN_POINTS])	mask = GetFaceMask(img2, landmarks2)	warped_mask = WarpImg(mask, M, img1.shape)	combined_mask = np.max([GetFaceMask(img1, landmarks1), warped_mask], axis=0)	warped_img2 = WarpImg(img2, M, img1.shape)	warped_corrected_img2 = ModifyColor(img1, warped_img2, landmarks1)	output_img = img1 * (1.0 - combined_mask) + warped_corrected_img2 * combined_mask	cv2.imwrite('output.jpg', output_img)if __name__ == '__main__':	main('./1.png', './2.png')

标签: #python安装cv2模块的方法