葫芦与瓢 2019-04-02
如今,随着技术的不断进步,“变脸”技术不再是四川喜剧的“独门武功”。运用机器学习的方法,我们同样可以实现人脸“融合”。当然这里说的人脸融合指的是将两个人的人脸照片进行融合,至于融合的比例,要按照自己的喜好来定。
核心原理介绍
1).首先是人脸识别的原理介绍
要进行人脸的融合,且融合后两个人脸的位置应该大体一致,这要如何才能做到呢?首先便是人脸的检测,只有检测到了人脸,才能进行接下来的工作。人脸的检测,我们采用的是Dlib函数库,帮助我们进行人脸的检测。如下图所示:
得到人脸的位置后,接下来就是对于人脸的关键点的定位,什么是关键点的定位呢,说的通俗一点,就是确定图片中人脸的关键特征的位置,比如眼睛,嘴巴,鼻子的位置。而这些关键点又被称为Landmark。
2).如何检测这些关键点呢
这里又利用到了Dlib库,Dlib库为我们提供了68个标记点的Dlib官方人脸识别模型,用于构建Dlib的特征提取器,帮助我们进行关键点的提取。提取效果如下图所示:
image
有了关键点,相当于我们有了两张脸的数据,接下来我们将针对于这些关键点进行融合,融合的公式代码如下所示:
points = (1 - alpha) * np.array(points1) + alpha * np.array(points2)
其中alpha是我们的融合系数,而points1和points2分别代表两张图的关键点,points表示关键点融合的结果。接下来便是对points运用delaunay算法,这个算法将返回一个三角形列表。而至于效果则如下图所示:
image
由上图可以看出,两张图中的三角形抓取了近乎相似的区域。由上面我们可以得到图片1中关键点的和图片2中关键点的集合,以及合成图片的关键点的集合。
我们也由delaunay算法得到了确定的三角形。接下来我们选取图片1中的三角形和合成图中的三角形进行仿射变换,也就是将图片1中的三角形对应的映射到合成图片当中去,关于仿射变换,我们可以使用opencv中的getAffineTransform函数进行。
对于图片2,我们也采取同样的处理方式,最后是基于我们提供的融合系数,进行两张人脸的融合。部分源码如下图所示:
image
上述的morph_faces函数,用来进行人脸的融合,首先是读取两张人脸图片,然后是获取两张人脸的关键点,分别命名为points1和points2并对points1和points2进行融合,命名为points,然后利用morph_triangle函数对人脸进行仿射变换,实现两张人脸的对齐,并将对齐的两张人脸按照融合系数进行融合。
软件界面设计
以上就是关于人脸融合的基本原理,接下来就是运行界面的搭建了。
image
一共有4个按钮,分布是打开图片1,打开图片2,人脸融合和退出软件。
image
中间有3张图片,前2张都是原始图片,最后一个合成图片,尤其是合成图片那里是关键中关键:
image
这里面的main函数是调用后台的算法函数,然后再输入一个融合系数,就是entry.get()里面获取的用户输入的融合系数,一般默认是0.5,即两个脸一半一半。
后台的算法会把两种图片利用cv2和dlib进行处理合成,然后生成一个新的合成图片
最后我们用PIL库把图片读出来,然后显示在界面上即可。
看一下效果
最后,小编找了几位明星,进行人脸的融合,效果如下图所示:
image
这篇文章主要用了很多计算机视觉方面的库opencv,这个库很博大精深,几乎玩图像的无人不知无人不晓,有兴趣的同学可以研究一下。