Python人脸合成,秒变胡歌王俊凯

2019-06-20 20:52:06 浏览数 (1)

如今,随着技术的不断进步,“变脸”技术不再是四川喜剧的“独门武功”。运用机器学习的方法,我们同样可以实现人脸“融合”。当然这里说的人脸融合指的是将两个人的人脸照片进行融合,至于融合的比例,要按照自己的喜好来定。人脸融合的效果我们先看视频。

01

变脸视频,一睹为快

下面小编就带领大家从以下的几个方面来打造一款向上图所示的人脸识别软件。

02

核心原理介绍

1).首先是人脸识别的原理介绍

要进行人脸的融合,且融合后两个人脸的位置应该大体一致,这要如何才能做到呢?首先便是人脸的检测,只有检测到了人脸,才能进行接下来的工作。人脸的检测,我们采用的是Dlib函数库,帮助我们进行人脸的检测。如下图所示:

得到人脸的位置后,接下来就是对于人脸的关键点的定位,什么是关键点的定位呢,说的通俗一点,就是确定图片中人脸的关键特征的位置,比如眼睛,嘴巴,鼻子的位置。而这些关键点又被称为Landmark。

2).如何检测这些关键点呢

这里又利用到了Dlib库,Dlib库为我们提供了68个标记点的Dlib官方人脸识别模型,用于构建Dlib的特征提取器,帮助我们进行关键点的提取。提取效果如下图所示:

有了关键点,相当于我们有了两张脸的数据,接下来我们将针对于这些关键点进行融合,融合的公式代码如下所示:

代码语言:javascript复制
points = (1 - alpha) * np.array(points1)   alpha * np.array(points2)

其中alpha是我们的融合系数,而points1和points2分别代表两张图的关键点,points表示关键点融合的结果。接下来便是对points运用delaunay算法,这个算法将返回一个三角形列表。而至于效果则如下图所示:

由上图可以看出,两张图中的三角形抓取了近乎相似的区域。由上面我们可以得到图片1中关键点的和图片2中关键点的集合,以及合成图片的关键点的集合。

我们也由delaunay算法得到了确定的三角形。接下来我们选取图片1中的三角形和合成图中的三角形进行仿射变换,也就是将图片1中的三角形对应的映射到合成图片当中去,关于仿射变换,我们可以使用opencv中的getAffineTransform函数进行。

对于图片2,我们也采取同样的处理方式,最后是基于我们提供的融合系数,进行两张人脸的融合。部分源码如下图所示:

上述的morph_faces函数,用来进行人脸的融合,首先是读取两张人脸图片,然后是获取两张人脸的关键点,分别命名为points1和points2并对points1和points2进行融合,命名为points,然后利用morph_triangle函数对人脸进行仿射变换,实现两张人脸的对齐,并将对齐的两张人脸按照融合系数进行融合。

03

软件界面设计

以上就是关于人脸融合的基本原理,接下来就是运行界面的搭建了。

  • 运行界面的搭建采用的是tkinter进行处理,
  • 首先是打开文件夹,读入我们想要进行融合的人脸
  • 然后是输入融合的比例系数,如果我们忘记输入融合系数的话,软件默认的系数便是0.5
  • 最后点击我们的“人脸融合”按钮,软件便会展示出人脸融合后的效果。
  • 这里需要注意的是,输入的两张图片大小不需要严格的一致,程序会自动帮大家进行图片大小的调整。

一共有4个按钮,分布是打开图片1,打开图片2,人脸融合和退出软件。

中间有3张图片,前2张都是原始图片,最后一个合成图片,尤其是合成图片那里是关键中关键:

这里面的main函数是调用后台的算法函数,然后再输入一个融合系数,就是entry.get()里面获取的用户输入的融合系数,一般默认是0.5,即两个脸一半一半。

后台的算法会把两种图片利用cv2和dlib进行处理合成,然后生成一个新的合成图片

最后我们用PIL库把图片读出来,然后显示在界面上即可。

04

看一下效果

最后,小编找了几位明星,进行人脸的融合,效果如下图所示:

这篇文章主要用了很多计算机视觉方面的库opencv,这个库很博大精深,几乎玩图像的无人不知无人不晓,有兴趣的同学可以研究一下!

0 人点赞