总序

“换脸”Python实现共分为四个部分,第一部分是原理讲解,第二部分是Python实现,第三部分是效果改进,前三部分都是单张图片,第四部分是应用到视频。

网上的很多教程没有原理讲解,所以也许可以照猫画虎,但没有总体的理解,就很难有自己的改进方法,希望本四次的分享对你有帮助。


第一部分 原理

换脸原理很简单,就是两个图,把第一张图(图甲)中的人脸换成第二张图(图乙)中的人脸。具体分成4步:

1. 确定人脸位置
2. 把图乙的人脸大小和方向调节得和图甲中的差不多
3. 挖掉图甲中原来的人脸,换成图乙中的人脸

当然,为了使人脸衔接更自然,会做一些简单的脸边缘的过渡,同时会做一些亮度、边缘模糊等调整。

步骤

上面原理中的三个步骤,也是三个难题,其实很简单。我觉得没有必要从太细节上追究每一个点,但宏观上必须了解它大概是怎么进行的。

1. 确定人脸位置

为了确定人脸位置,有专门训练好的 dlib 库,它会找出人脸的特征点(中图),dlib 是一个训练好的模型,可以直接下载其参数。然后用 opencv 的凸包函数得到人脸形状(右图)。此处不是将整张人脸截下,而是将眼睛,口,鼻等关键部位截出来,当然自己也可以截出整张脸。如下图,左图是原始图片,中图是 dlib 检测人脸,右图是最终得到包含关键部位的人脸的形状。

图1 确定人脸位置
这样,图样的方法处理图乙,得到人脸位置。
2. 把图乙的人脸大小和方向调节得和图甲中的差不多

这个的实现主要用仿射变换,及一些图片的旋转、缩放、调整图片分辨率等方法,具体实现也比较麻烦,能从总体上知道那些函数功能这样就好。

3. 挖掉图甲中原来的人脸,换成图乙中的人脸

这个用掩模的方法,就像图1中的最右面一张图,我有另外一张图,大小和其一致,但脸型部分全为0,其余部分全为1. 两张图相当于两个矩阵,两者对应元素相乘,就得到挖去脸的图片。此时如果我有另外一张脸,脸部全为1, 其余部分全是0,那么用两张图对应元素一一相加,就可以得到最终的换脸后的图片。

4. 衔接过渡脸的边缘

用上面的方法换的脸,看上去很不自然。此时可以把“新脸”的亮度调整得和“旧脸”差不多,边缘进行一些模糊,让其过渡自然。

结语

以上便是基本思路,有了这样的思路,就可以根据需要很好得进行算法修改。下面进入第二部分。