当前位置: 首页 > 编程日记 > 正文

百变冰冰!手把手教你实现CVPR2021最新妆容迁移算法

作者:小潘师兄

来源:AI算法与图像处理

简介

在本文中,我们从不同的角度将妆容迁移问题分解为两步提取-分配过程。为此,我们提出了一种基于风格的可控GAN模型,该模型由三个部分组成,每个部分分别对应于目标风格编码、人脸特征提取和化妆融合。具体地,特定于部件的样式编码器将参考图像的组件式构图样式编码为中间潜在空间W中的样式代码。样式代码丢弃空间信息,因此对空间错位保持不变。另一方面,样式码嵌入了组件信息,使得能够从多个参考中灵活地进行部分补码编辑,该样式码与源标识特征一起集成到一个具有多个AdaIN层的补码融合解码器中,以生成最终结果。

架构图:

解析:提出的方法(SCGAN)的概述。在(a)中,参考图像y被分解为三部分。part-specific样式编码器提取每个部分的特征,并将其映射到一个分离的样式潜在空间W。人脸身份编码器提取源图像x的人脸身份特征。妆容融合解码器将样式码w与人脸身份特征融合,生成最终结果xˆ. (b) 显示PSEnc的映射模块(c) 是MFDec中装有AdaIN层的熔合块。

思路 & 效果

大概了解原理之后,我们开始实现:

步骤1:对人脸的五官(眼睛、眉毛、鼻子、嘴唇等等)进行分割。

步骤2:使用SCGAN 进行上妆。

这里的人脸五官分割模型采用的是:

https://github.com/zllrunning/face-parsing.PyTorch

先看一下效果:

卧槽,什么鬼,效果并不是很好,那么是SCGAN 的模型问题吗?

存在的问题:首先仔细回想一下处理的过程,来查看,第一步处理的时候发现,分割的效果并不理想,嘴唇位置和闭嘴的分割效果非常的差,这也导致了最后的效果并不是理想。因此,需要想办法优化分割的效果。

那么如何优化分割的效果?

重新训练?不存在的。

第一没有数据集,第二没有必要

我们知道深度学习模型的性能其实和数据集是有很强的相关性的,这里我们仔细观察一下人脸分割所采用的数据集 https://github.com/switchablenorms/CelebAMask-HQ

基本上采用的是使用仅包含人脸头部区域作为输入和制作label的,因此,这里尝试对输入的图片进行处理,裁剪成仅包含人脸区域的作为输入 (裁剪人脸区域)

因此现在的步骤变成:

1、裁剪人脸

2、对人脸的五官(眼睛、眉毛、鼻子、嘴唇等等)进行分割

3、使用SCGAN 进行上妆

详细操作流程

裁剪人脸:

这里直接使用 dlib, 裁剪出人脸的区域。

import cv2
import dlibimg = cv2.imread("bingbing.jpg")
height, width = img.shape[:2]face_detector = dlib.get_frontal_face_detector()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detector(gray, 1)def get_boundingbox(face, width, height, scale=1.3, minsize=None):"""Expects a dlib face to generate a quadratic bounding box.:param face: dlib face class:param width: frame width:param height: frame height:param scale: bounding box size multiplier to get a bigger face region:param minsize: set minimum bounding box size:return: x, y, bounding_box_size in opencv form"""x1 = face.left()y1 = face.top()x2 = face.right()y2 = face.bottom()size_bb = int(max(x2 - x1, y2 - y1) * scale)if minsize:if size_bb < minsize:size_bb = minsizecenter_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2# Check for out of bounds, x-y top left cornerx1 = max(int(center_x - size_bb // 2), 0)y1 = max(int(center_y - size_bb // 2), 0)# Check for too big bb size for given x, ysize_bb = min(width - x1, size_bb)size_bb = min(height - y1, size_bb)return x1, y1, size_bbif len(faces):face = faces[0]x,y,size = get_boundingbox(face, width, height)
cropped_face = img[y-50:y+size,x:x+size]
cv2.imwrite("cropped_face.jpg", cropped_face)

这里我偷偷换了一个素材。

输入:

输出:

这样子我们就完成了裁剪工作。

人脸五官分割:

使用的模型:

https://github.com/zllrunning/face-parsing.PyTorch

1)克隆项目:

git clone git@github.com:zllrunning/face-parsing.PyTorch.git

如果遇到下载问题参考之前的教程:

完美解决Github上下载项目失败或速度太慢的问题

2)环境配置 & 预训练模型:

因为这里,没有写环境相关相关的配置

但是这个人脸五官分割的模型是基于 BiSeNet(https://github.com/CoinCheung/BiSeNet)

这里推荐torch 1.6.0  torchvision 0.7.0,因为可以兼容后续的 SCGAN 模型,这里以cuda10.1为例 (已测试没有问题)

# 安装
conda install pytorch==1.6.0 torchvision==0.7.0 cudatoolkit=10.1 -c pytorch
或
pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html

下载过慢,可以考虑换源,例如清华源、阿里源等,或者指定源(参考链接https://www.cnblogs.com/yuki-nana/p/10898774.html)

预训练模型:https://drive.google.com/open?id=154JgKpzCPW82qINcVieuPH3fZ2e0P812

将下载好的模型,放在 res/cp 路径下。

3)运行:

修改 test.py 文件

对下面的输入进行修改

if __name__ == "__main__":evaluate(dspth='/home/zll/data/CelebAMask-HQ/test-img', cp='79999_iter.pth')

假设这里将要分割的图片放在test文件夹下,则这里修改成:

if __name__ == "__main__":evaluate(dspth='test', cp='79999_iter.pth')

然后运行即可看到res/test_res 文件夹下有生成的结果

这里建议输入的图片后缀,不要是 png 否则会由于生成的文件名冲突导致我们想要的文件被覆盖了。此时生成的结果包含:

假设左边为图1,右边图2。图1 是对分割的结果进行上色,图2是对应的label 值,但是由于原始的label设置成很小的值(0-18),很难看出区别来。

具体的label对应的含义 ,可以参考下面

https://github.com/switchablenorms/CelebAMask-HQ/tree/master/face_parsing

这里我们已经完成了对人脸的分割处理

使用SCGAN 上妆:

1)克隆项目:

(https://github.com/makeuptransfer/SCGAN)

但是由于作者做了一些优化(version 2),目前没有把预训练的模型补充上去,因此这里可以别人fork的版本下载(https://github.com/tommy19970714/SCGAN/)

git clone git@github.com:tommy19970714/SCGAN.git

2)预训练权重下载:

https://drive.google.com/file/d/1t1Hbgqqzc_rV5v3gF7HuJ-xiuEVNb8sh/view

将 G.pth 和 vgg.pth 分别放在 文件夹 "./checkpoints" (自己新建一个)和 "./"(项目下) 下

3)修改必要文件和运行:

修改 test.py 文件,对下面的输入进行修改

首先这里还要做一些预处理,对label 进行一些变换。

这里作者已经给了代码(scripts/handdle_parsing.py),输入的图片是刚刚人脸分割获得的图 2,就是那个看上去黑乎乎的图片

修改 handdle_parsing.py 中的 root 和保存结果的结果名即可
root="./data/bingbing.png" # 假设输入的是
paths=["bingbing.png"]

运行后得到新的

将这两张图片分别放在./MT-Dataset/images/non-makeup/bingbing.png (原始图片)和/MT-Dataset/parsing/non-makeup/bingbing.png 即可

修改test.txt 文件

原始
non-makeup/xfsy_0444.png makeup/XMY-078.png
non-makeup/xfsy_0444.png makeup/licEnH3rBjSA.png
修改后
non-makeup/bingbing.png makeup/XMY-078.png
non-makeup/bingbing.png makeup/licEnH3rBjSA.png

最后运行即可看到结果(result 文件夹下)

如果你希望对保存的结果样式进行修改,可以看

/SCGAN/models/SCGAN.py 中的 imgs_save 函数 (这里就不展开)

如果你想尝试更多妆容可以去下载

http://colalab.org/projects/BeautyGAN

相关文章:

Vlan 4096的限制原因

为什么80%的码农都做不了架构师&#xff1f;>>> VLAN配置的最大可能值为4094&#xff0c;它的由来如下所述&#xff1a; IEEE802.1q协议也就是“Virtual Bridged Local Area Networks”&#xff08;虚拟桥接局域网&#xff0c;简称虚拟局域网&#xff09;协议&#…

Hive 数据模型

Hive 数据模型 Hive 数据表有五种类型&#xff1a;内部表&#xff0c;外部表&#xff0c;分区表&#xff0c;桶表&#xff0c;视图表&#xff0c;默认以 tab 分隔 * MySQL (Oracle) 表默认以逗号分隔&#xff0c;因此&#xff0c;要想导入 MySQL(Oracle) 数据&#xff0c;需要设…

完整中英文世界国家级联下拉列表插件【前端版】

为什么80%的码农都做不了架构师&#xff1f;>>> 这个小东西是之前小项目上临时增加功能的产物&#xff0c;那时候在网上找了很久都没有能用的插件&#xff0c;要么是数据残缺少得可怜&#xff0c;还有就是实现手段非常低效不可维护那种&#xff0c;各种奇拔问题&am…

何时使用margin和padding?

margin和padding的意义相信大家都很清楚&#xff0c;可是在具体应用中&#xff0c;到底应该使用哪一个&#xff0c;就比较难于判断了。 这篇文章 说得挺清楚的&#xff0c;在这里翻译一下&#xff0c;供参考。 何时应当使用margin 需要在border外侧添加空白时。 空白处不需要…

10年IT老兵给新人程序员的几点建议

【CSDN 编者按】对于很多计算机专业的同学而言&#xff0c;“进大厂”已经成为毕业后职业道路的首选。但是面试官最喜欢什么样的应届生你知道吗&#xff1f;在校期间应该为找工作做哪些准备&#xff1f;除了技术好&#xff0c;在职场中还有哪些必备软实力&#xff1f;今天&…

asp.net文件上传下载的简单实现

使用FileUpload上传&#xff1a; protected void btnUpload_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { /*通过文件扩展名判断文件类型*/ string fileExt System.IO.Path.Ge…

JAVA数组的定义及用法

数组是有序数据的集合&#xff0c;数组中的每一个元素具有同样的数组名和下标来唯一地确定数组中的元素。 1. 一维数组 1.1 一维数组的定义 type arrayName[]; type[] arrayName; 当中类型(type)能够为Java中随意的数据类型&#xff0c;包含简单类型组合类型&#xff0c;数组名…

英特尔公布新技术路线图,将为 AWS、高通代工芯片

编译|刘春霖出品|AI科技大本营(ID:rgznai100)图源|IC photo今天英特尔宣布其旗下的工厂将开始制造高通芯片&#xff0c;并公布了公司有史以来最详细的制程工艺和封装技术路线图&#xff0c;希望在 2025 年前赶上台积电、三星电子。除了公布其近十多年来首个全新晶体管架构 Ribb…

epoll相关资料整理

http://www.cppblog.com/converse/archive/2008/10/13/63928.htmlepoll相关资料整理 学习epoll有一段时间了,最近终于有一个服务器采用了epoll模型,从中积累了一些epoll的资料.个人感觉目前可以找到的epoll相关的资料太少了,因为epoll仅被linux 2.6以上版本内核所支持,它的应用…

18.绝对路径和相对路径

什么是绝对路径&#xff08;Absolute Pathname&#xff09;&#xff1f; 1.绝对路径必定由“/”开头 2.绝对路径是为档案/文件的所在位置做指向 3.在任何时候&#xff0c;都可以用绝对路径来找到我们想要的文件 PS&#xff1a;绝对路径只对当前所在目录有效。 什么是相对路径&a…

IE的box模型显示bug

原作者charlee、原始链接http://tech.idv2.com/2007/01/02/ie-box-model-bug/以及本声明。 box模型即由<div>等块元素的 margin、padding、border、width、height 等属性构成的显示模型&#xff0c;它是CSS布局的基础。通过设置<div>的各种属性&#xff0c;可以得到…

AI 能匹敌程序员了吗?OpenAI 新研究展​示 NLP 大模型的局限性

作者&#xff1a;Ben Dickson来源&#xff1a;数据实战派Codex在一篇新论文中&#xff0c;OpenAI 的研究人员展示了 Codex 的详细信息&#xff0c;它是一种生成软件源代码的深度学习模型。Codex 可以为 OpenAI 和 GitHub 联合开发的 “AI 配对程序员” 工具 Copilot 提供支持。…

MSLicensing​中断远程桌面连接

---------------------------中断远程桌面连接---------------------------客户端无法建立跟远程计算机的连接。导致这个错误的可能的原因是:1) 远程计算机上的远程连接可能没有启用。2) 已超出远程计算机上的连接最大数。3) 建立连接时出现了一个网络错误。------------------…

如何恢复,迁移,添加, 删除 Voting Disks

如何恢复&#xff0c;迁移&#xff0c;添加, 删除 Voting Disks 恢复流程 在11gR2 之前&#xff0c;我们可以直接直接使用dd命令对voting disk进行备份。 DD示例 备份votedisk盘&#xff1a; [rootraw1 bin]# dd if/dev/raw/raw2 of/home/oracle/voting_disk.bak 恢复votedisk盘…

跨站脚本攻击(XSS)FAQ

原作者charlee、原始链接http://tech.idv2.com/2006/08/30/xss-faq/以及本声明。 该文章简单地介绍了XSS的基础知识及其危害和预防方法。Web开发人员的必读。译自 http://www.cgisecurity.com/articles/xss-faq.shtml。 简介 现在的网站包含大量的动态内容以提高用户体验&…

linux中的for命令

bash shell提供了for命令&#xff0c;用于创建通过一系列值重复的循环。每次重复使用系列中的一个值执行一个定义的命令集。for命令基本格式为&#xff1a;for var in listdo commandsdone1.读取列表中的值 #!/bin/bash #basic for command for test in a b c d e f doecho The…

终于有人把计算机视觉讲明白了 。。。

机器学习是目前比较热门的技术&#xff0c;包含深度学习、强化学习、对抗学习、对偶学习、迁移学习、分布式学习、以及元学习等内容。得益于大数据、大模型、大计算的发展&#xff0c;深度学习在计算机视觉、语音处理、自然语言方面相继取得了突破&#xff0c;达到甚至超过了人…

mysql启动与关闭(手动与自动)

手动管理mysql的启动与关闭 [rootmysql ~]# service mysql start --手动启动mysql Starting MySQL. SUCCESS! [rootmysql ~]# service mysql stop --手动关闭mysql Shutting down MySQL.. SUCCESS! [rootmysql ~]# mysqld --verbose --help --查看MySQL的默认参数的具体值 如果…

C#中抽象类和接口的区别

一、抽象类&#xff1a;抽象类是特殊的类&#xff0c;只是不能被实例化&#xff1b;除此以外&#xff0c;具有类的其他特性&#xff1b;重要的是抽象类可以包括抽象方法&#xff0c;这是普通类所不能的。抽象方法只能声明于抽象类中&#xff0c;且不包含任何实现&#xff0c;派…

echo向文件中写入

echo命令向一个文件写入内容的方法详解&#xff0c;感兴趣的朋友可以参考下。 覆盖型写法 (文件里原来的内容被覆盖)echo "aaa" > a.txtecho aaa > a.txt 添加型写法 (新内容添加在原来内容的后面&#xff09;echo "aaa" >> a.txtecho aaa >…

火山引擎向企业客户开放上万款抖音同款特效

你喜爱的抖音特效&#xff0c;在其他平台上也能使用了。 7月28日&#xff0c;抖音联合火山引擎举办特效技术开放日&#xff0c;首次披露抖音特效的生产流程和技术原理。活动中&#xff0c;火山引擎宣布已向企业客户开放了上万款抖音同款特效&#xff0c;包括猴哥、漫画惊讶脸…

5.1 python的缩进

python 并不像其他语言一样要求以大括号来分辨逻辑&#xff0c;仅仅使用 tab 键&#xff08;默认的四个空格&#xff09;来区分代码。比如 ainput(Please input a num: ) b0 if int(a)>b: print(a>0) else: print(a<0) 返回结果&#xff1a;当输入小于0时&#xff0c;…

centOS 自动安装php

centos下安装php#yum install -y php这个只安装PHP建议安装运行库及MySQL的支持#yum install -y php php-devel php-mysql如果你的系统是CentOS 5.6那么上面这条命令安装的是PHP 5.1,要安装 PHP 5.3则执行下面的命令:#yum install -y php53 php53-devel php53-mysql自动安装启动…

strcpy_s与strcpy的比較

strcpy_s和strcpy()函数的功能差点儿是一样的。strcpy函数&#xff0c;就象gets函数一样&#xff0c;它没有方法来保证有效的缓冲区尺寸&#xff0c;所以它仅仅能假定缓冲足够大来容纳要拷贝的字符串。在程序执行时&#xff0c;这将导致不可预料的行为。用strcpy_s就能够避免这…

抖音发布特效数据报告:每五个投稿有一个使用特效

7月28日&#xff0c;抖音与火山引擎联合举办特效技术开放日&#xff0c;首次发布了《抖音特效数据报告》。报告显示&#xff0c;2021上半年 &#xff0c;抖音平台平均每天上线超过100个新款特效&#xff1b;平均每五个投稿里&#xff0c;就有一个使用特效&#xff0c;特效已经成…

11G RAC 进程启动顺序

本文转自 张冲andy 博客园博客&#xff0c;原文链接&#xff1a;http://www.cnblogs.com/andy6/p/6041171.html &#xff0c;如需转载请自行联系原作者

使用 jQuery 简化 Ajax 开发

JSON 入门指南 <script languageJavaScript typetext/javascript> </script> <script languageJavaScript typetext/javascript> </script> 级别&#xff1a; 初级 廖 雪峰, 撰稿人 2008 年 8 月 22 日 JSON 即 JavaScript Object Natation&#xf…

AI一眼识别这是什么鸟 “我们来找茬”十级选手诞生

话说&#xff0c;你能看出这三只鹦鹉有什么不一样吗&#xff1f;脸盲如我&#xff0c;要使出玩“我们来找茬”的十级能力。AWSL&#xff0c;鹦鹉鹦鹉&#xff0c;傻傻分不清楚。结果&#xff0c;AI一顿操作猛如虎&#xff0c;进行了判断&#xff1a;左边的是桃面牡丹鹦鹉&#…

stm32时钟树讲解

1.管理好时钟&#xff0c;功耗才能更低

安全攻防实战:使用winlogonhack获取系统密码

安全攻防实战&#xff1a;使用winlogonhack获取系统密码S.S.F simeon摘要 在网络安全事件频发的今天&#xff0c;很多人都在抱怨&#xff0c;为什么我的系统被入侵了&#xff0c;我的主页被修改了&#xff0c;在入侵后&#xff0c;我采取了一些安全加固措施&#xff0c;可是没…