手把手:用OpenCV亲手给小扎、Musk等科技大佬们做一张“平均脸”(附Python代码)

百家 作者:大数据文摘 2017-11-22 04:32:01

作者:SATYA MALLICK

编译:HAPPEN、Chloe、钱天培


紧盯这张照片5秒钟,你能否看出任何异样呢?

照片中的女性同时拥有白人血统、西班牙人血统、亚洲人血统以及印度人血统

  • 她皮肤光彩无暇,眼神扑朔迷离,似乎美得不真实。

  • 她并不真实存在,但她也并非完全虚构。

创造她的正是文摘菌今天要介绍的一项黑科技——“平(da)均(zhong)脸”

文摘菌今天的手把手专栏将为大家介绍,如何用OpenCV随心所欲帮各种人组合“平均脸”。完整的python代码可在后台回复“平均脸”获取。

让我们先来看两张文摘菌好奇的平均脸。

成功男性科技界企业家平均脸长什么样?

下图是小扎,马斯克,拉里·佩奇,和杰夫·贝索斯的平均脸。杰夫·贝索斯似乎拉低了发量平均值,不过幸好这张平均脸并没有全秃。

小扎,马斯克,拉里·佩奇,和杰夫·贝索斯的平均脸

奥斯卡最佳女主角平均脸又长什么样呢?

下图为布丽·拉尔森,朱丽安·摩尔,凯特·布兰切特,詹妮弗·劳伦斯的平均脸。这张平均脸真是非常迷人了!她的牙齿比企业家平均脸洁白整齐得多。一点也不意外!

近四届奥斯卡最佳女主角:布丽·拉尔森,朱丽安·摩尔,凯特·布兰切特,詹妮弗·劳伦斯的平均脸

最后,文摘菌还用平均脸生成了一张文摘家主编大大们的平均脸,翻到文末看大大们的颜值哦~

“平均脸”的历史

为何平均脸的颜值看起来如此之高?在进入代码实操之前,让我们先来简单了解一下平均脸的历史。

“平均脸”源于达尔文的堂兄Francis Galton在1878年提出的一种新的摄影技术——通过对准眼睛来合成人脸。他认为,通过生成罪犯的平均脸,人们就可以根据面部特征来预测一个人是否是罪犯。很显然,他的假设是错误的——你不能通过照片来预测一个人是否是罪犯。然而,“平均脸”这个创意却流传了下来。

此后,多项研究证明,平均脸其实比个体脸更具有吸引力。在其中一项研究中,研究者们生成了22名入围2002年德国小姐评选决赛的选手的平均脸,并让吃瓜群众打分。结果显示人们认为平均脸比22位选手的脸更有吸引力,包括赢得比赛的柏林小姐。紧接着人们发现,柏林小姐的长相和这张平均脸非常接近。噢!原来柏林小姐的脸吸引人,正是因为她的脸接近平均水平!

按常理说,平均脸不应该很平庸吗?为什么平均脸吸引人?

根据进化假说,有性繁殖的动物会寻找长着平均脸的伴侣,因为偏离平均值可能产生不利的突变。平均脸也是对称的,因为脸的左边和右边的变化是平均的。(文摘菌顿悟瞬间——原来“大众脸”可以是个褒义词。)

接下来,就让我们一起来OpenCV学习创造“平均脸”!

美国总统的平均脸:从Carter到Obama

文摘菌将以美国总统的脸为例(因为美国总统像清晰且高度一致!),给大家介绍生成平均脸的关键技术步骤,完整的python代码可在后台回复“平均脸”获取。

  • 步骤一:面部特征检测

首先,我们需要使用dlib库在每张面部图像上建立68个面部基准点。安装dlib库的步骤较为复杂,如果你无法成功安装dlib,可以跳过该步,使用文摘菌为大家准备的面部基准点示例文档(即为faces文档中的txt文件)。

面部特征检测案例


  • 步骤二:坐标转换

我们手头的面部图像的尺寸很可能是不一样的,同时面部也很可能处于图像的不同位置,所以我们需要标准化面部特征,并把它们放到同一参考坐标系下。

为了实现这一点,我们将图像大小转为600*600,把左眼(外眼角)放在像素位置(180,200)右眼(外眼角)放在像素位置(420,200)。我们称该坐标系统为输出坐标系统,称原始图像坐标为输入坐标系统。

为什么我要选择上述点呢?

因为我希望确保两只眼睛的点都在一个水平线上面部中心大约在离顶端三分之一高度的位置。所以我将眼角位置设为(0.3*宽,高/3)(0.7*宽,高/3)

在原始图像的68个面部基准点中,左眼外眼角右眼外眼角分别在基准点36和45。因此我们可以利用这两个点计算图像的相似变换矩阵(旋转、变换和缩放),将输入坐标系统的点进行转换为输出坐标系统

3000*2300大小的输入图像通过相似变换矩阵转为600*600大小的输出图像

什么是相似变换矩阵?(不想学数学的同学可以简单略过)

如果你想对一个正方形作出转换,使正方形在x和y方向上分别缩放s_x和s_y,同时将它旋转theta角度,再在x和y方向上平移t_x和t_y,对应的相似变换矩阵就是


对于一个(x, y)点来说,它的新位置就将会是


代码实现很简单(这里你需要安装cv2库):

cv2.estimateRigidTransform(inPts, outPts, False)

相似变换矩阵是一个2*3矩阵,用于转换点坐标或整个图像。矩阵前两列用于转换与缩放最后一列用于变换(如移位)

这儿还存在一个小问题:

OpenCV要求你至少提供3个点,虽然通过两点你就可以计算相似变换矩阵了。好消息是,我们可以简单假设第三个点,让它与已知的两个点组成等边三角形,然后我们就可以使用 estimateRigidTransform了。

得到相似变换矩阵后,我们就可以用来它将输入图像和基准点转换生成输出坐标了。我们使用warpAffine来转换图像,用transform来转换点(详见代码)

  • 步骤三:人脸对齐

第二步后直接生成的平均脸

上一步中,我们能够将所有的图像和关键点变换到输出图像坐标系。现在所有图像都是相同大小,并且眼睛的两角都分别对齐。似乎对这些图像每个像素的值进行平均我们就能得到平均脸啦。但如果你真这么做了,会得到上图这样的结果。当然眼睛肯定是对齐的,但是其他面部特征都没对齐。

如果我们知道两张输入图像的点如何一一对应,那我们很容易就能将两张图像完美对齐。然而我们并没有这些信息。我们只知道这些输入图像68个对应点的位置。所以,我们可以用这68个点把图像分成若干三角形区域,然后对齐这些区域,再对像素值进行平均

平均基准点的Delaunay三角剖分

首先,我们需要计算这68个基准点的坐标平均值,我们利用这68个点(图6蓝色点)以及输出图像边界上的8个点(上图绿色点)来计算Delaunay三角剖分(上图红色边框)。更多Delaunay三角剖分细节请看这里(https://www.learnopencv.com/delaunay-triangulation-and-voronoi-diagram-using-opencv-c-python/)

Delaunay三角剖分将图像分解成若干三角形。Delaunay三角剖分的结果是一个三角形列表,用76个点(68个人脸基准点+8个边界点)的序号表示。下面的矩阵展示了部分三角形列表,我们看到,关键点62、68和60形成一个三角形32、50和49形成另一个三角形,等等。

[

62 68 60

32 50 49

15 16 72

9 8 58

53 35 36

…  ]

基于Delaunay三角剖分的图像扭曲

至此,我们计算出了人脸基准点的平均位置,并用这些位置计算出Delaunay三角剖分,将图像分成若干三角形。如上图所示,左图是变换后输入图像的Delaunay三角剖分,中图是平均关键点的三角剖分。注意,左图的三角形1对应中图的三角形1。用左图三角形1的三个顶点及其对应的中图三个顶点计算变换矩阵。用这一变换将左图三角形1中的所有像素变换到中图的三角形1中去。对左图每个三角形重复该过程,得到右图这一结果。右图只是将左图扭曲到平均脸。

  • 第四步:人脸平均

现在,激动人心的时刻到了!

经过了上述处理之后,我们就可以对这些照片的像素取平均值,得到神奇的平均脸了。

当然,你也可以生成对称脸,将一张脸及其镜像进行平均。比如:

对奥巴马的图像(左)及其镜像(右)进行平均得到对称脸(中)

彩蛋部分!文摘菌也制作了编辑大大们的平均脸。噔噔噔噔!

   欢迎评论猜他们都是谁呀:)

如果你也想自己制作平均脸,可以在大数据文摘后台回复“平均脸”获取Python代码



课程推荐

数据科学实训营第4期

优秀助教推荐|姜姜

作为一枚对数据分析的理解仅限于Excel的小白,曾经一直认为通过写代码来分析数据是件无比高大上的事。可是,在文摘的数据科学实训营居然就实现了!

手把手的教学方式,助教和同学们热烈的交流讨论,让我慢慢地觉得一行行代码如此亲切。而当把自己头脑中的构思通过代码实现,看到结果的那一刻,真是无比激动!

经过Kaggle、天池的案例的历练,对这些数据比赛也开始兴趣盎然,有没有小伙伴有兴趣一起去玩一玩的?

作为第4期的北美地区助教,寄语各位学员:前方高能,请准备好足够的时间,如果你能按时提交作业,结业时一定脱胎换骨。






志愿者介绍


回复志愿者”加入我们

往期精彩文章

点击图片阅读

联合国曝光AI杀手机器人,这可能是你见过最恐怖的视频

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接