本帖最后由 fantomas 于 2018-10-19 10:22 编辑
使用OpenCV进行面部交换(换脸)
在本教程中,我们将学习如何使用C ++和Python中的OpenCV和DLib将一个图像上的面部换成另一个完全不同的面部。 为什么Face-Swap很难? 主要存在一下的四个方面的问题: 首先,不同的人面部的几何形状差别很大 其次,脸部的光线与皮肤的色调相结合可以使图像看起来非常不同。 第三,面部的姿势(或摄像机角度,如果你愿意)可以显着变化。 最后,皮肤的质地可以从光滑到几乎像皮革一样坚硬。 本文提出的技术将解决前两个问题,但不是最后两个问题。 FaceSwap:使用OpenCV逐步完成 1.面部对齐:要将一个面替换为另一个面,我们首先需要将一个面大致放在另一个面上,以便覆盖下面的面。一个例子如图1所示。 图1:左:检测到的面部标志和凸壳 中:delaunay三角剖分凸壳上的点 右:用过仿射warp三角形进行面部对齐 1.1面部地标检测 两个面的几何形状是非常不同的,因此我们需要稍微扭曲源面部以覆盖目标面部,但我们也希望确保我们不会将其扭曲到无法识别的位置。为此,我们要实现这一目标。首先使用dlib 检测两个图像上的面部标志。但是与面部变形不同,我们不会也不应该使用所有点进行面部对齐。我们只需要在图像中显示的面部外边界上的点。 1.2查找凸壳 在计算机视觉和数学术语中,点或形状集合的边界称为“壳”。没有任何凹陷的边界称为“凸壳”。在图1中,左侧的图像显示了dlib检测到的面部标志使用红色的点来描述,并且点的凸包显示为蓝色。可以使用OpenCV的convexHull函数计算一组点的凸包。 Python: - # 使用dlib来获得面部的标志点,类型是数组(包含所有检测到的点)
- hullIndex = cv2.convexHull(points, returnPoints = False)
- # hullIndex 是一个点的索引组成的向量 ,来形成凸壳
复制代码1.3 Delaunay三角剖分 对齐的下一步是对凸包上的点进行Delaunay三角剖分。三角剖分显示在图1中间的图像中。这使我们可以将面部分成更小的部分。 1.4仿射经线三角形 面部对齐的最后步骤,考虑到源面部和目标面部之间的相应三角形,我们将源面部三角形仿射到目标面部上。但是正如你在图1的右图所示,对齐脸部并将一张脸贴在另一面上几乎看起来不自然。由于两个图像之间的光照和肤色差异,接缝是可见的。下一步显示如何无缝地组合两个图像。 2.无缝克隆:良好的技术理念就像是好的魔法。好的魔术师使用物理学,心理学和良好的旧手法相结合来实现令人难以置信的。仅从图像仿射warp上看结果非常糟糕(图1中的左图)。但将它与无缝克隆相结合,结果是神奇的! 它是OpenCV 3中的一项功能,允许您将源图像的一部分(由掩膜标识)无缝复制到目标图像上。 - output = cv2.seamlessClone(src, dst, mask, center, cv2.NORMAL_CLONE)
复制代码图2:src-源面部 dst-目标面部 output-面部交换结果 使用fillConvexPoly通过填充凸包来计算mask,并且中心是包含mask的边界框的中心。
|