上一节我们通过VAE网络完成了人脸生成效果。VAE网络一个特性是会把人脸编码成一个含有200个分量的向量,反过来说在特定分布范围内的含有200个分量的向量就对应一张人脸。由于向量之间可以进行运算,这就意味着我们把两张不同人脸A,B分布转换成两个不同向量z_A,z_B,然后我们使用向量运算例如z_AB = z_A *(1 - alpha) + z_B *alpha,就能将两个向量以一定比例合成一个新向量,该新向量就会对应一个人脸,而且这个人脸就会同时具有人脸A和B的特点,如果我们增大参数alpha,那么生成向量对应的人脸特征就会更像人脸B,如果我们减少alpha的值,生成向量对应的人脸就更像人脸A.

接下来我们看看如何实现人脸的转变特效,首先我们先出数据图片中选出具有特定特征的人脸图片,例如”戴墨镜“,然后使用编码器得出”戴墨镜“人脸图片的特征向量,然后我们再选取不带墨镜的人脸图片,计算其特征向量,然后使用向量运算将两个向量结合起来,这样我们就能把后面不带墨镜的人脸转换成带墨镜的模样。

我们看看相应代码实现:

def  morph_faces(start_image_file, end_image_file):alpha = np.arange(0, 1, 0.1) atttribute_specific = att[att['image_id'].isin([start_image_file, end_image_file])]att_specific = atttribute_specific.reset_index()data_flow_label = imageLoader.build(att_specific, 2) #加载满足给定条件的图片example_batch = next(data_flow_label)example_images = example_batch[0]example_labels = example_batch[1]z_vectors = vae.encoder.predict(example_images)#获得人脸图像的关键向量fig = plt.figure(figsize = (18, 8))counter = 1img = example_images[0].squeeze()sub = fig.add_subplot(1, len(alpha) + 2, counter)sub.axis('off')sub.imshow(img)counter += 1for factor in alpha: #通过变化参数让一个向量滑向另一个向量changed_z_vector = z_vectors[0] * (1 - factor) + z_vectors[1] * factorchanged_image = vae.decoder.predict(np.array([changed_z_vector]))[0] #根据新向量绘制人脸图像img = changed_image.squeeze()sub = fig.add_subplot(1, len(alpha) + 2, counter)sub.axis('off')sub.imshow(img)counter += 1img = example_images[1]sub = fig.add_subplot(1, len(alpha) + 2, counter)sub.axis('off')sub.imshow(img)plt.show()

上面函数先将输入的两张图片转换成各自对应的向量,然后使用向量运算,通过变化中间参数的形式让一个向量不断的”滑向“另一个向量,由此形成的效果是,其中一张人脸图片参数”渐变“效果,随着向量不断滑向另一个向量,所生成的人脸图片越来越具备目标向量的特性,我们调用上面函数看看实现效果:

start_image_file = '000238.jpg'
end_image_file = '000193.jpg' #戴墨镜人脸
morph_faces(start_image_file, end_image_file)

上面代码运行后所得结果如下:

处于最左和最右边的图像时我们输入的两张人脸图片,中间人脸是将一边人脸图片对应的向量滑向另一边时所产生的人脸,我们注意到中间人脸图片是左右两张人脸图片特征的混合。回到deepfake或zao这样的变脸应用,他们的原理就是先将计算原来视频中人脸变化所对应的不同向量,然后计算用户的人脸向量,然后将用户人脸向量”滑向“视频中人脸当前表情对应向量从而实现用户人脸展现出视频中人脸的同样表情,当前它们的实现比我们这里介绍的要复杂得多。

接下来我们看如何让一个没有带墨镜的人脸“自然而然”的带上墨镜,首先要做的是计算所有戴墨镜的人脸图片对应的向量,将这些向量加总求平均值得向量A,这样我们就能用向量A表达出”带墨镜“这一特征,然后计算所有没有带墨镜的人脸图片所对应的向量,将这些向量加总求平均值得向量B,将该向量减去”戴墨镜“所对应的特征向量,这样就得出滑动方向,然后将不带墨镜的人脸图片对应向量慢慢根据给定方向滑动,这样我们就可以天衣无缝的给原来没带墨镜的人脸带上墨镜,实现如下:

def  get_vector_from_label(label, batch_size):data_flow_label = imageLoader.build(att, batch_size, label = label) #读取所有图片origin = np.zeros(shape = vae.z_dim, dtype = 'float32') #原点向量current_sum_pos = np.zeros(shape = vae.z_dim, dtype = 'float32') #将所有含有给定特征的图片向量加总current_n_pos = 0 #统计当前具备给定特征的图片数量current_mean_pos = np.zeros(shape = vae.z_dim, dtype = 'float32') #求加给定特征向量加总后的平均值向量current_sum_neg = np.zeros(shape = vae.z_dim, dtype = 'float32') #不具备给定特征的向量加总current_n_neg = 0 #不具备给定特征的向量个数current_mean_neg =  np.zeros(shape = vae.z_dim, dtype = 'float32') #不具备给定特征的向量加总后求平均所得向量current_vector = np.zeros(shape = vae.z_dim, dtype = 'float32') current_dist = 0 #给定图片特征向量与给定特征向量之间的距离print('label: ' + label) #label表示给定特征print('image : POS move : NEG move : distance : delta distance')while current_n_pos < 10000:batch = next(data_flow_label)im = batch[0]attribute = batch[1]z = vae.encoder.predict(np.array(im)) #计算图片对应的特征向量z_pos = z[attribute == 1] #抽取出具有给定特征图片所对应的向量z_neg = z[attribute == -1] #抽取出不具备给定特征的图片所对应的向量if len(z_pos) > 0:current_sum_pos = current_sum_pos + np.sum(z_pos, axis = 0) #将所有含有给定特征的向量加总current_n_pos += len(z_pos)new_mean_pos = current_sum_pos / current_n_pos #计算平均向量#随着图片加载越多,具有给定特征的图片也就越多,于是得到的平均向量在位置上就会发生改变movement_pos = np.linalg.norm(new_mean_pos - current_mean_pos) #计算特征向量加总求平均后所得向量的变化量if len(z_neg) > 0:current_sum_neg = current_sum_neg + np.sum(z_neg, axis = 0) #将不具备给定特征的人脸向量加总current_n_neg += len(z_neg)new_mean_neg = current_sum_neg / current_n_neg #计算平均向量#随着读入图片的增多,不具备给定特征的图片也会增多,于是平均向量也会发生改变movement_neg = np.linalg.norm(new_mean_neg - current_mean_neg) #计算平均向量的改变量current_vector = new_mean_pos - new_mean_neg #获得连接给定特征的平均向量和不具备给定特征的平均向量之间的连接向量new_dist = np.linalg.norm(current_vector) #获得两个向量之间的距离dist_change = new_dist - current_distprint(str(current_n_pos) + '      :  ' + str(np.round(movement_pos, 3))+ '      :  ' + str(np.round(movement_neg, 3))+ '      :  ' + str(np.round(new_dist, 3))+ '      :  ' + str(np.round(dist_change, 3)))current_mean_pos = np.copy(new_mean_pos)current_mean_neg = np.copy(new_mean_neg)current_dist = np.copy(new_dist)if np.sum([movement_pos, movement_neg]) < 0.08: #当向量该变量足够小时我们结束对平均向量的计算current_vector = current_vector / current_distprint("Found the " + label + ' vector')breakreturn  current_vector  def  add_vector_to_images(feature_vec):  #将给定图片的向量滑向给定特征平均向量,于是让图片具备给定特征n_to_show = 5factors = [-4, -3, -2, -1, 0, 1, 2, 3, 4]example_batch = next(data_flow_generic)example_images = example_batch[0]example_labels = example_batch[1]z_points = vae.encoder.predict(example_images) #获得图片对应特征向量fig = plt.figure(figsize = (18, 10))counter = 1for i in range(n_to_show):img = example_images[i].squeeze()sub = fig.add_subplot(n_to_show, len(factors) + 1, counter)sub.axis('off')sub.imshow(img) #显示没有变化前图片counter += 1for factor in factors:  #让图片对应向量滑向给定特征平均向量changed_z_point = z_points[i] + feature_vec * factorchanged_image = vae.decoder.predict(np.array([changed_z_point]))[0] #根据滑动后向量创建人脸图片img = changed_image.squeeze()sub = fig.add_subplot(n_to_show, len(factors) + 1, counter)sub.axis('off')sub.imshow(img)counter += 1plt.show()

接着我们随机采用若干张没有戴墨镜的人脸图片,然后先调用上面代码计算戴墨镜这一特征对应的向量,然后将人类图片对应向量沿着戴墨镜所对应特征向量的方向滑动,这样就能使得不带墨镜的人脸变成戴墨镜,代码如下:

BATCH_SIZE = 500
eyeglasses_vec = get_vector_from_label("Eyeglasses", BATCH_SIZE) #先获得"带墨镜"对应的特征向量
add_vector_to_images(eyeglasses_vec) #让没有带墨镜的人脸图片添加上带墨镜效果

上面代码运行后结果如下:

从中我们看到,最左边对应没有戴墨镜的人脸图片,最右边的人脸则是戴墨镜的效果,到这里我们节介绍完使用VAE网络实现人脸生成的技术方法

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:

人脸生成黑科技:实现人脸转变特效,让人脸自动戴墨镜相关推荐

  1. 人脸生成黑科技:使用VAE网络实现人脸生成

    上一节我们描述了VAE网络的数学原理,特别强调了它能把输入数据隐射到一个区域内,这种特性带来一个特点是,如果将两个不同数据输入网络得到两个区间,这两个区间要是有重合的话,我们在重合的区域内取一点让解码 ...

  2. Python人脸识别黑科技(二):教你使用python+Opencv完成人脸解锁

    继上一篇"Python人脸识别黑科技(一):50行代码运用Python+OpenCV实现人脸追踪+详细教程+快速入门+图像识",那么今天我们来讲关于使用python+opencv+ ...

  3. 揭秘腾讯微视人脸技术「黑科技」,基于GAN的人脸魔法特效

    随着小视频越来越流行,兼具趣味与人物个性的人脸特效成为小视频软件的标配,美颜自不必说,现在的人脸特效可谓"千变万化",人脸年轻化.变欧美范儿.发型改变.各种表情.胖瘦等. 不仅人脸 ...

  4. 人脸识别撞脸名画_人脸识别“黑科技”蚂蚁金服“遇见名画中的自己”火爆东博会...

    ​也许你撞过衣服.撞过名字,但是你是否想过你会与世界名画中的"古人"撞脸?当下,蚂蚁金服首次把黑科技"遇见名画中的自己"带进了第13届中国-东盟博览会. 东博会 ...

  5. 超级黑科技代码!Python打造电脑人脸屏幕解锁神器附带接头暗号

    前言:让我的电脑认识我 我的电脑只有认识我,才配称之为我的电脑! 今天,我们用Python实现高大上的人脸识别技术! Python里,简单的人脸识别有很多种方法可以实现,依赖于python胶水语言的特 ...

  6. 戴上口罩AI变“脸盲”?口罩人脸识别黑科技来袭

    疫情期间,口罩在全国抗疫中起到了关键作用.但在口罩成为每一位公民"标配"的同时,对诸如"刷脸"支付.高铁闸机身份认证等需要人脸识别的场景提出了挑战. 口罩.帽子 ...

  7. 追平iPhone!搭载IFAA人脸识别黑科技,这款国产安卓手机厉害了

    2017年9月,iPhone X上市带动了无数个Face ID相关的话题.苹果Face ID技术采用的是3D结构光技术,由于苹果收购了提供该技术的以色列公司,使得iPhone X 的Face ID拥有 ...

  8. cad求和插件_黑科技 | 无BIM建模下平面CAD自动生成门窗表

    如果你接到的施工图既不是用天正出的,也不是用revit出的,还得统计门窗表,那么你需要读完这篇文章. 为了能够让自己和所有底层同行们从这项无脑又烧脑的机械劳动中解脱,C君近期利用茶余饭后的时间开发了一 ...

  9. 人脸识别黑科技正式入侵,消亡还是苏醒?人工智能测试势不可挡!

    摘要:当前,人脸识别技术已经在诸多领域取得广泛应用,但其风险也一直为外界关注,尤其是对风险容忍度较低的金融行业来说,用户验证环节如果出现漏洞,就可能造成巨大损失.本文将以一个项目实例出发,分享在测试人 ...

  10. 高考监考引入人脸识别黑科技?更多高新监控技术为高考保驾护航!

    高考是我国选拔考试中最公平相对最综合的选拔方式,同时,也是一场决定资源分配的考试.虽然说高考对人生的影响并不是决定性的,但是对于大多数考生来说,高考是一项重要.严肃的人生选择,因此对于高考作弊的防范也 ...

最新文章

  1. python免费试听-小栈春季编程免费试听课 倒数6天!
  2. “融合、智能、绿色”施耐德电气线上工博以全生命周期解决方案助推数字化
  3. 安卓学习笔记43:初试开源框架Volley
  4. python2ide_python_2_IDE安装
  5. NUAA 南航操作系统实验
  6. Jspx.net Framework 6.38发布
  7. Linux学习第一节课学习心得
  8. 基于LSTM的沪深股票价格预测
  9. 设计模式六大原则详解
  10. Android系统篇之—-Android中的run-as命令引出升降权限的安全问题(Linux中的setuid和setgid)
  11. cadence常用快捷键及小技巧(画斜线、开balloons等)
  12. javaweb学习笔记(六)
  13. 带噪声音信号的产生(MATLAB)
  14. 全球及中国大豆蛋白行业市场需求趋势及未来战略规划建议报告2022-2028年
  15. Android自定义日期区间选择,类似12306酒店入住的日期选择
  16. 【LeetCode】222. Count Complete Tree Nodes 解题报告(Python)
  17. 长尾词组合,常见的3种长尾词组合方法
  18. 单片机快速开平方的算法
  19. 华为HCNP基础内容
  20. 输入矩形边长 计算周长和面积

热门文章

  1. 现代数字信号处理课后作业【第六章】
  2. Dual Thrust策略
  3. 学习WEB的心理路程
  4. 读书笔记1:《C++沉思录》
  5. 腾讯QQ空间登录的方法实现方式与验证过程分析
  6. 计算机网络七层体系结构
  7. Linux局域网多人聊天软件
  8. vs2019键盘钩子_Windows消息钩子
  9. 简单的安卓木马制作(实现外网控制)
  10. 云服务器上Mongodb被拖库,黑客向我勒索0.015 BTC