SSAT妆容迁移
转自AI Studio,原文链接:SSAT妆容迁移 - 飞桨AI Studio又是展示的一天,妆容迁移之SSAT PADDLE版本,你值得拥有1. 效果展示又是展示的一天呢,枯燥且乏味的show time。哈哈哈哈哈哈哈哈哈哈请原谅我笑得这么大声就是第一列的女生用的第二列的妆容,就是第四列的结果,第三列是看第二列妆容按照第一列的脸型扭曲的效果咋样,可以忽略如果你想试一下死亡芭比粉的口红,是不是就不
转自AI Studio,原文链接:SSAT妆容迁移 - 飞桨AI Studio
又是展示的一天,妆容迁移之SSAT PADDLE版本,你值得拥有
1. 效果展示
又是展示的一天呢,枯燥且乏味的show time。哈哈哈哈哈哈哈哈哈哈
请原谅我笑得这么大声
就是第一列的女生用的第二列的妆容,就是第四列的结果,第三列是看第二列妆容按照第一列的脸型扭曲的效果咋样,可以忽略
如果你想试一下死亡芭比粉的口红,是不是就不需要亲自买一只就可以看到效果了?请把项目有用打在公屏上。
如果看官是有女朋友的男生想看自己女朋友涂紫色口红的样子,你可以fork
如果看官本身是女生,想看闺蜜涂紫色口红的样子,你可以fork
咱说一个数,200fork一个项目,冲冲冲!!!!!!!!!!!!!
这个时候肯定有人好奇,怎么不用男生当试验呢?我肯定试过了,但是怎么可能放出来嘛,是吧,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。
这个时候肯定有人会问,小帅哥,这个是这么做出来的呢?对吧,我知道的,我很懂的哦,请允许我喝口水娓娓道来。
好了好了,严肃起来,严肃起来
2. 论文名称:SSAT: A Symmetric Semantic-Aware Transformer Network for Makeup Transfer and Removal
论文PDF我也放在项目里面了
原论文官方项目地址:https://github.com/Snowfallingplum/SSAT
作者的视频论文讲解:https://www.bilibili.com/video/BV1k34y1t7jk?spm_id_from=333.788.top_right_bar_window_history.content.click
知乎的论文讲解: https://zhuanlan.zhihu.com/p/494364754
那个数据集呢,没有哦,因为我是直接把官方提供的预训练模型参数直接给转成paddle的参数文件格式了,哈哈哈,我不会训练哦。
3.妆容迁移的任务描述:
把人物B的妆容迁移到人物A身上,也就是输入的是两张人物人脸照片得到一张新的人脸照片C。C照片需要保持A的人脸内容特征,但是需要保持B的妆容。
4.本项目注意点
就是这个人脸呢。要占整张图片的很大一部分,不然效果就不太好,尽量减少让模型减少受背景干扰的机会。不要像上方这个图片一样,这就是一个错误典型!!!!!!
另外模型输入的是4个部分信息。这个时候有人好奇了,为啥是四个部分信息呢?不是只要输入模型两张人脸就好了吗,一张target(提供人脸内容信息),一张reference(妆容信息)。这个时候这就体现这篇论文创新之处了,它为了给模型一个人脸各个部分的先验信息,所以对于target和reference对应的人脸解析信息也作为输入给模型了。那么这个时候有人会说:大佬大佬,那么我们可没有能够得到人脸先验信息的轮子呀,咋办?
我会允许这种事情的发生?不可能,绝对不可能,于是我这个人脸解析项目特意弥补了这方面的空白。大家只要用就行了。
另外再注意一下,人脸解析项目自动把图片reshape成512*512大小的,然后模型输出的人脸解析的图片也是512*\512大小的,然后本项目这里reference和target我也自动resize成512*\512大小的,也就是请你如果想用本项目实验的话请输入的图片都是正方形,防止人脸因为resize变形。
5.模型解读
我也懒得把现有的资料搬运一遍,如果真的想去学习这个模型,那么我所有资料信息上方已经提供了。大家该看自己看,这边我提供一份我原创的模型框架图,方便对照着代码理解看。这里展示的图片是png格式,项目里面也提供pdf版本的。
6.代码使用讲解
In [19]
import cv2
import numpy as np
def load_parse(parse):
parse = cv2.imread(parse, cv2.IMREAD_GRAYSCALE)
# print(parse)
# parse = self.rotate(parse, angle)
h, w = parse.shape
result = np.zeros([h, w, 18])
for i in range(18):
result[:, :, i][np.where(parse == i)] = 1
result = np.array(result)
return result
# load_parse("1.png").shape
In [20]
'''
makeup_face_img就是reference ,16行代码图片读取路径改一下
makeup_parse就是reference的人脸解析信息,19行代码图片读取路径改一下
makeup_none_img就是target,21行代码图片读取路径改一下
makeup_none_parse就是target的人脸解析信息,25行代码图片读取路径改一下
'''
import numpy as np
from PIL import Image
from paddle.vision.transforms import functional as F
import paddle
makeup_face_img = cv2.cvtColor(cv2.imread("12.jpg", flags=cv2.IMREAD_COLOR),
cv2.COLOR_BGR2RGB)
makeup_face_img = F.resize(makeup_face_img, [512,512])
makeup_parse = load_parse("12.png")
makeup_none_img = cv2.cvtColor(cv2.imread("refer.jpg", flags=cv2.IMREAD_COLOR),
cv2.COLOR_BGR2RGB)
makeup_none_img = F.resize(makeup_none_img, [512,512])
makeup_none_parse = load_parse("refer.png")
makeup_face_img = (paddle.to_tensor(makeup_face_img).astype("float32")/127.5-1).unsqueeze(0).transpose([0,3,1,2])
makeup_parse = paddle.to_tensor(makeup_parse).unsqueeze(0).transpose([0,3,1,2]).astype("float32")
makeup_none_img = (paddle.to_tensor(makeup_none_img).astype("float32")/127.5-1).unsqueeze(0).transpose([0,3,1,2])
makeup_none_parse = paddle.to_tensor(makeup_none_parse).unsqueeze(0).transpose([0,3,1,2]).astype("float32")
data = {"non_makeup":makeup_none_img,"makeup":makeup_face_img,"non_makeup_parse":makeup_none_parse,"makeup_parse":makeup_parse}
In [21]
from paddle_model import MakeupGAN as pmm
pm = pmm()
pm.set_state_dict(paddle.load("paddleweight.pdparams"))
test_pair_img = pm.test_pair(data)
In [ ]
print(test_pair_img)
In [23]
test_pair_img = (test_pair_img+1)*127.5
test_pair_img = test_pair_img.numpy()
test_pair_img = test_pair_img.transpose(0, 2, 3, 1)[0]
test_pair_img = test_pair_img.astype(np.uint8)
cv2.imwrite('ep1och.png',cv2.cvtColor(test_pair_img,cv2.COLOR_RGB2BGR)) # ep1och.png就是输出结果
True
7. 一些小问题
官方作者团队给出的代码是有瑕疵的,我也提了issue并且得到作者的肯定。这个问题是我把权重从pytorch迁移到paddle后仔细阅读了一下源码发现的,但是呢,我把这个问题申明放在项目最后,就表示这是不影响使用的。
更多推荐
所有评论(0)