前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己动手制作“平均脸”【1】

自己动手制作“平均脸”【1】

作者头像
叶锦鲤
发布2018-03-15 12:54:44
4.5K0
发布2018-03-15 12:54:44
举报
文章被收录于专栏:悦思悦读悦思悦读

有趣的“平均脸”

大家想必看到过很多合成的“平均脸”图片吧。

有按国家、民族合成的:

也有针对政要明星合成的,例如这张,韩中日三国明星平均脸:

“平均脸”的历史

虽然现在很流行,但是,其实平均脸的历史相当悠久。

1878年,英国的弗朗西斯·高尔顿爵士(Sir Francis Galton)发明了一种创造出“平均”面容的技术。

弗朗西斯·高尔顿爵士,英国维多利亚时代的博学家、人类学家、优生学家、热带探险家、地理学家、发明家、气象学家、统计学家、心理学家和遗传学家;也是《物种起源》作者查尔斯·达尔文的表弟。*

这一方法是通过将许多人的照片合成为一张照片完成的。

当时具体的做法是:照片叠加——给多个人,比如20个人,照相,将每个人照片所需的曝光时间缩短为1/20,通过20次曝光得到一张“平均”照片。

弗朗西斯·高尔顿最初合成平均脸的目的是将不同“种类”的人(例如:囚犯、精神病患者等等)视觉化,以期得到这类人的“原型”(共同特征)。

但结果却意外的发现,这样合成的人脸却比用于合成大部分(甚至是全部)都要好看!

虽然高尔顿爵士的初衷没有达到,合成平均脸的方法却保留了下来。

新技术让人人可制作“平均脸”

随着技术的发展,照片不再需要物理底片,合成也不再需要复杂的曝光冲印技术,通过一些简单的操作就能做到,人人都可以上手。

想不想自己动手制作一张周围人的平均脸?

一点都不复杂,只要知道了用Image Morphing技术叠加照片的原理,再会写几行简单的代码,就能顺利完成。

Image Morphing技术的原理相当简单:给定两张图片I和J,我们通过叠加(或者叫做混合)I和J来获得一张中间状态的图片M。

I和J的叠加由一个参数[0,1]区间内的参数alpha来控制。当alpha=0时,M就等同于I,而aphla=1时,M就为J。

换言之, M中的每一个像素M(x,y),都可以通过这样一个公式来得到它的值:

M(x,y) = (1 – alpha)·I(x,y) + alpha·J(x,y)

当alpha=0.5的时候,I和J就五五开,平均贡献了M。如果I和J是两张人脸照片的话,M自然也就成了它们的“平均脸”。

看起来好容易哦,那我们赶紧找两张照片来试试吧!就用这两张:

这两张照片alpha=0.5后直接叠加的结果是这样的:

这也不是人脸呀!先别急,看看为什么会这样?

从这张“重影图”上不难看出来,之所以这样,是因为最基本的五官都没有对齐。

如果我们事先把两个人的眼睛和嘴对齐,效果就不会是这样的了。

叠加两张*对齐的*人脸

叠加图片I和图片J的时候,首先应该建立两张照片中像素的对应关系

对I中的某一个像素点(xi,yi),我们不是直接在J中取同样位置的点就可以了,而是要找到它在J中内容上的对应点 (xj,yj)。

然后再进一步找到M中这两个点叠加之后应当处在的位置(xm,ym),最后再用下列式子得出M中对应点的像素值:

xm = (1-alpha) · xi + alpha · xj ym = (1-alpha) · yi + alpha · yj 算式-1

对一个像素点我们这样做,对整幅图片,则是将上面的过程运用到它的每一个像素点上:

M(xm,ym) = (1 – alpha)·I(xi,yi) + alpha·J(xj,yj) 算式-2

很好,我们已经知道从原理上该怎么叠加两张图了。

其中关键的一步就是:找到对应点。

其实对应点叠加的方法可以用来叠加任何图片,不仅限于人脸。

不同物体的叠加,真正的区别就在于找到像素点之间的对应关系!一旦对应关系找到,直接运用算式-2就好了。

划分区域对应人脸

既然我们现在要做的是叠加人脸,那么首先当然要找到人脸上的对应点。

人脸是生活中最常见的事物,我们每一个人都非常熟悉。

一个人的脸如果用简笔画画出来,可以简化为:脸型+五官(眉毛、眼睛、鼻子、嘴)。

那么如果我们要叠加两个人的脸的话,自然就是要针对他们的脸型和五官形制求平均。

人的五官如果用图形来描绘,都是不规则图形。如果要完全不走样的获取一个人的眼睛、眉毛、鼻子或者嘴,需要绘制非常复杂的形状。

实际上,我们没有必要这样做,而是可以通过一种非常简单的近似方法,把一张人脸分割成若干三角形的区域,然后再来叠加两张脸上对应的三角区域。

分割方法如下:

1. 获取人脸特征

在图片中获取人脸和人脸特征(脸型+五官)。

我们先在每张面孔上获取68个面部基准点(如下图)。

2. Delaunay 三角剖分
在获得了68个面部基准点之后,我们结合人脸所在的矩形的四个顶点和每条边的中心点,将人脸所在的矩形分割成如下图所示的三角形的组合。

这一方法又称为Delaunay三角剖分。更多细节请看:https://www.learnopencv.com/delaunay-triangulation-and-voronoi-diagram-using-opencv-c-python/

叠加经过仿射变换的Delaunay剖分三角形

Delaunay三角剖分将图像分解成若干三角形后,再分别对齐各个三角形区域,对其中像素值进行平均。

Step-1:找到合成图片中的面部特征点

使用前述的算式-1,根据图像I和图像J中已经获得的76个点,在叠加的结果图像M中找到76个点(xm, ym)

Step-2: 计算原图到目标图像的仿射变换

现在我们在图像I,J和M中分别得到了76个点,以及由这76个点剖分而成的三组三角形。

从图像I中选取一个三角形ti,在M中找到对应区域tm,通过ti三个顶点到tm三个顶点的映射关系来计算ti到tm的仿射变换。

同理计算出tj到tm的仿射变换。

Step-3:扭曲Delaunay剖分三角形

对于图像I中的一个三角形,使用step-2中计算出的放射变换,将其中每一个像素通过仿射变换对应到M中对应的位置去。

重复这个过程,处理图像I中的每一个三角形,得到一个扭曲的(warped)图像I'。用同样的方法处理图像J,获得扭曲的图像J'。

Step-4:叠加两张脸

在step-3中我们已经得到了扭曲的图像I'和图像J'。这两个图像就可以直接使用算式-2进行叠加了。最后得到叠加结果。

叠加多张人脸

算式-2用于叠加2张人脸,在alpha=0.5时求取的是两张脸的平均。

那么我们把算式推广一下,从图像I和图像J推广为图像I1, I2, I3, ..., In;令alpha=1/n;则算式-2变形为如下:

M(xm,ym) = 1/n · [I1(xi1, yi1) + I2(xi2, yi2) + ... ... + In(xin, yi_n)]

由此,我们也就得到了n张脸的平均。

用这个方法,我们可以得到6位美国总统的平均脸:

他们平均之后的样子是这样的:

上面的过程看着还挺复杂是不是?其实,如果使用opencv + dlib,只要几十行代码就能搞定!

今天先讲原理,下次我们再来分析具体技术和代码

代码在此:https://github.com/juliali/AverageFace

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智汇AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 有趣的“平均脸”
  • 大家想必看到过很多合成的“平均脸”图片吧。
  • 有按国家、民族合成的:
    • 1. 获取人脸特征
      • 2. Delaunay 三角剖分
        • 在获得了68个面部基准点之后,我们结合人脸所在的矩形的四个顶点和每条边的中心点,将人脸所在的矩形分割成如下图所示的三角形的组合。
          • 叠加经过仿射变换的Delaunay剖分三角形
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档