作者: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杀手机器人,这可能是你见过最恐怖的视频