图像变形背后的想法很简单。给定两个图像我们想通过将图像和混合来创建中间图像。图像的混合由参数控制的是在0和1之间()。当为0时,变形看起来像,而当为1 时,变形看起来。天真的,您可以在每个像素上使用以下方程式混合图像

但是,使用上面的方程式将希拉里·克林顿国务卿和特德·克鲁兹参议员的图像设置为0.5,会产生以下可怕结果。

产生的图像令人不安,但同时也会给您尖叫。恳求您在融合图像之前以某种方式对齐眼睛和嘴巴。当您尝试在不先调整思路的情况下将两种不同的政治意识形态融合在一起时,就会得到类似的令人不安的结果,但我离题了。

因此,要将图像变形为图像,我们需要首先在两个图像之间建立像素对应。换句话说,对于图像中的每个像素,我们需要找到它在图像中的对应像素。假设我们神奇地找到了这些对应关系,我们可以分两步混合图像。首先,我们需要计算变形图像中像素的位置。由下式给出

(1) 

其次,我们需要使用以下公式找到像素的强度

(2) 

而已。我们完了。现在,我们去投票给特朗普。开玩笑!就像特朗普一样,我省略了一些重要的细节。为图像I中的每个像素找到图像J中的对应点与在美国和墨西哥之间建立10英尺的墙一样困难。可以做到,但是它很昂贵,并不是真正必要的。

但是很容易找到一些点对应关系。为了使两个不同的对象(如猫的脸和人的脸)变形,我们可以单击两个图像上的几个点以建立对应关系,并为其余像素插值结果。接下来,我们将详细了解“脸部变形”的完成方式,但是相同的技术可以应用于任何两个对象。

脸部变形:逐步

可以使用以下步骤变形两个面。为了简单起见,我们将假定图像的大小相同,但这不是必需的。

1.使用面部特征检测找到点对应

让我们从获取相应点开始。首先,我们可以通过检测面部特征点来自动(或手动)获得很多。我使用dlib来检测68个对应点。接下来,我又增加了四个点(一个在右侧耳朵上,一个在脖子上,另外两个在肩膀上)。最后,我还添加了图像的角点和这些角点之间的中间点作为对应点。不用说,可以在头和脖子周围添加更多点以获得更好的结果,或者删除手动单击的点以获得稍微差一点(但是全自动的)的结果。

2. Delaunay三角剖分

从上一步开始,我们有两组80个点-每个图像一组。我们可以计算两组中对应点的平均值,并获得一组80个点。在这组平均点上,我们执行Delaunay三角剖分。Delaunay三角剖分的结果是由80点数组中的点的索引表示的三角形列表。在这种特殊情况下,三角剖分产生了149个三角形,将80个点连接在一起。三角剖分存储为三列数组。三角剖分的前几行如下所示。

三角剖分
38 40 37
35 30 29
38 37 20
18 37 36
33 32 30

它显示点38、40和37形成一个三角形,依此类推。三角剖分显示在下面的两个图像中。

请注意,两个图像中的三角形捕获了近似相似的区域。我们从点对应开始,现在由于三角剖分,我们有了三角形(或区域)对应。

3.扭曲图像和Alpha混合

为了更好地理解下面的描述,请在此处订阅我们的时事通讯以下载代码和图像。

现在,我们可以智能地融合两个图像。如前所述,混合量将由参数控制。使用以下步骤创建变形。

  1. 在变形图像中找到特征点的位置:在变形图像中,我们可以使用等式(1)找到所有80个点的位置。
  2. 计算仿射变换:因此我们在图像1中有一组80点,在图像2中有另一组80点,在变形图像中有第三组80点。我们也知道在这些点上定义的三角剖分。在图像1中选择一个三角形,在变形图像中选择一个相应的三角形,并计算仿射变换,该仿射变换将图像1中的三角形的三个角映射到变形图像中相应的三角形的三个角。在OpenCV中,可以使用getAffineTransform完成此操作。为每对149个三角形计算仿射变换。最后,重复图像2和变形图像的过程。
  3. 变形三角形:对于图像1中的每个三角形,使用在上一步中计算出的仿射变换将三角形内的所有像素变换为变形图像。对图像1中的所有三角形重复此操作以获得图像1的变形版本。类似地,获得图像2的变形版本。在OpenCV中,这可以通过使用warpAffine函数来实现。但是,warpAffine会获取图像,而不是三角形。诀窍是计算三角形的边界框,使用warpAffine扭曲边界框内的所有像素,然后遮盖三角形外部的像素。使用fillConvexPoly创建三角形蒙版。使用warpAffine时,请确保使用blendMode BORDER_REFLECT_101。与克林顿国务卿掩盖她的电子邮件相比,它掩盖了接缝。
  4. Alpha混合变形图像:在上一步中,我们获得了图像1和图像2的变形版本。可以使用公式(2)将这两个图像进行Alpha混合,这是您最终的变形图像。在代码中,我提供了变形三角形和alpha混合,将它们合并在一个步骤中。

脸部变形结果

应用上述技术的结果如下所示。中间的图像是左右图像的50%混合。此页面顶部的视频显示了具有不同alpha值的动画。动画是一种廉价的技巧,可以将变形中的许多缺陷隐藏起来。特德·克鲁兹(Ted Cruz)参议员会喜欢的。

大多数面部特征都很好地对齐了。脸部以外的图像部分排列得不太好,因为在该区域中对应的点较少。可以手动添加其他点来修复错位并获得更好的结果。

总结:

point 68

point 80

delaunay 149

图1三角映射

图2三角映射

比例Alpha混合

Delaunay

原文:https://www.learnopencv.com/face-morph-using-opencv-cpp-python/

--

face morhper的更多相关文章

随机推荐

  1. linux 显示不可见字符

    在Linux中,cat -A file可以把文件中的所有可见的和不可见的字符都显示出来,在Vim中,如何将不可见字符也显示出来呢?当然,如果只是想在Vim中查看的话,可以这样:%!cat -A在Vim ...

  2. centos7.5 配置sftp

    1.创建sftp组 groupadd sftp 2.sftp组的用户的home目录统一指定到/u01/sftp下 mkdir -p /u01/sftp/ 3.创建一个sftp用户,用户名为devsft ...

  3. 【转】TI DSP C6657学习之——编译静态库.lib

    熟悉C++开发的的小伙伴都知道,我们一般代码中往往要引入许多第三方编译好的库,有些是静态链接库static library, 有些是动态链接库dll.引入库的目的一是减少代码的编译时间,二是只提供函数 ...

  4. QEMU简介

    参考:What Is the Difference between QEMU and KVM? 注意:上面参考文章有个错误,他把KVM算成类型一虚拟化,应该是类型2虚拟化. 关于类型一虚拟化和类型二虚 ...

  5. HTML&CSS基础-常用选择器

    HTML&CSS基础-常用选择器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.html源代码 <!DOCTYPE html> <html> & ...

  6. MySQL加锁分析 (转)

    参考:MySQL 加锁处理分析.该文已经讲的很详尽了,也易懂,下面仅仅是个人做的总结. 一. 背景 1.1 隔离级别 1.2 加锁过程 逐条处理,逐条加锁. 1.3 两阶段锁2PL 1.4 gap锁 ...

  7. DeferredResult使用方式和场景

    为什么使用DeferredResult? API接口需要在指定时间内将异步操作的结果同步返回给前端时: Controller处理耗时任务,并且需要耗时任务的返回结果时: 当一个请求到达API接口,如果 ...

  8. MarkDowm——语法篇

    前言 文档地址: http://www.markdown.cn/ 为了自己更熟悉MarkDown的语法,做个练习吧,以后博文打算用MarkDown直接写了. 标题 Markdown 支持两种标题的语法 ...

  9. Flask - 四剑客 | templates | 配置文件 | 路由系统 | CBV

    Flask框架简介 说明:flask是一个轻量级的web框架,被称为微型框架.只提供了一个高效稳定的核心,其它全部通过扩展来实现.意思就是你可以根据项目需要进行量身定制,也意味着你需要不断学习相关的扩 ...

  10. (尚004)Vue计算属性之基本使用和监视

    所做效果预览: test004.html <!DOCTYPE html><html lang="en"><head> <meta char ...