最近看到Github上有个项目很火,于是尝试clone下玩玩。
项目名:animegan2-pytorch
项目地址:https://github.com/bryandlee/animegan2-pytorch

项目简介

AnimeGAN是来自武汉大学和湖北工业大学的一项研究,采用的是神经风格迁移 + 生成对抗网络(GAN)的组合。

AnimeGAN从去年就已经提出,使用的是Tensorflow框架,目前该项目已开发出了第二代版本,支持pytroch框架。

原论文:AnimeGAN: A Novel Lightweight GAN for Photo Animation
https://github.com/TachibanaYoshino/AnimeGAN/blob/master/doc/Chen2020_Chapter_AnimeGAN.pdf

网络结构(图片节选自原论文,原理暂不细究):

该项目可以实现将真人头像动漫化,例如下面的动图所示:

项目上手

文件预览

由于国外服务器下载较慢,本项目所有文件以及所需下载的其它文件我均做了备份。获取方式可以跳转到文末。

samples:用来放置一些示例图片
weghts:权重文件
colab_demo/demo.ipynb:两个使用案例
convert_weights.py:用来将权重文件夹里的tensorflow模型转换成pytorch模型文件
hubconf.py:在Pytorch.Hub上获取预加载模型

在使用中,只需要用到两个文件:
1、demo.ipynb
2、weights文件夹(内含四个模型,对应不同图片大小、美化程度、鲁棒性等…)

环境安装

首先在jupyter lab中打开demo.ipynb,然后根据import来配置环境。

Pytorch 安装

项目需要使用Pytorch框架,框架的安装可以看我之前的博文:
超简单的pytorch(GPU版)安装教程(亲测有效)

cmake安装

在进行dlib库安装时,直接安装会报错:

CMake must be installed to build the following extensions: dlib

在此之前,需先进行cmake安装。
安装方式:

pip install cmake

face_recognition安装

安装完cmake后,先别急着装dlib,先安装face_recognition,这里面包含了一个版本的dlib。
安装方式:

pip install face_recognition

dlib检查与安装

安装好face_recognition之后,内部自带了一个dlib,此时可尝试运行demo中的第二段程序,如果dlib无报错,可不进行下面的步骤。
若报错,则可能是dlib的版本与python的版本不匹配,需卸载重装。
卸载方式:

pip uninstall dlib

若使用pip进行dlib的安装,大概率会报错,因此需将dlib的包下载下来本地安装。

下面是dlib不同版本和python版本的对应关系

python3.5版本:19.4.0版本
python3.6版本:19.6.0版本;
python3.7版本:19.14.0版本
python3.8版本:19.19.0版本;

我的安装的python版本为3.8,因此我需要下载dlib的19.19.0版本。
下载链接:https://pypi.org/project/dlib/19.19.0/#files

下载的是.tar.gz格式的文件:
下载好后需进行解压,在命令行切换到解压后的文件夹,运行:

python setup.py

运行好之后,相应的dlib版本就安装完毕。

scipy安装

scipy是科学工具包,内含很多计算公式,后面有用到,安装比较简单:

pip install scipy

requests安装(可选)

玩过爬虫的都知道requests可以很方便的向服务器发送请求,后面测试图片如果需要获取网络资源,则需安装此库,本地图片加载可不用安装。
安装方式:

pip install  requests

特征点检测数据库下载

前面安装过的dlib可用来检测人脸特征,但库本身并不带特征点检测库,运行时会报错:

Unable to open shape_predictor_68_face_landmarks.dat

解决方式:
将shape_predictor_68_face_landmarks.dat该文件放置在项目同文件夹下即可。
该文件在文末我备份的文件中已添加。

权重文件放置

运行代码第一段,它会用torch.hub.load来下载模型文件,如果你的网速不快,很可能会下载中断,产生报错。其实,下载的文件和克隆的项目文件一样,只不过会在C盘的缓冲区进行额外添加。
添加位置如图所示:

它会在相应文件夹下生成两个文件夹:

下载失败没关系,只要把项目内的相应文件拷贝进去即可。
第一个文件内容(即项目文件)

第二个文件内容(存放权重文件)

放好之后,在此运行第一段代码,就不会联网去下载,而会提示文件已存在。

代码功能解读

第一段代码,主要用来设置环境。

#@title Load Face2Paint modelimport torch
from PIL import Imagedevice = "cuda" if torch.cuda.is_available() else "cpu"
model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", device=device).eval()
face2paint = torch.hub.load("bryandlee/animegan2-pytorch:main", "face2paint", device=device, side_by_side=True)

第二段代码,核心代码,通过dlib将人脸部分进行裁切,并检测出所有人脸特征点,进行标注,产生图片。

#@title Face Detector & FFHQ-style Alignment# https://github.com/woctezuma/stylegan2-projecting-imagesimport os
import dlib
import collections
from typing import Union, List
import numpy as np
from PIL import Image
import matplotlib.pyplot as pltdef get_dlib_face_detector(predictor_path: str = "shape_predictor_68_face_landmarks.dat"):if not os.path.isfile(predictor_path):model_file = "shape_predictor_68_face_landmarks.dat.bz2"os.system(f"wget http://dlib.net/files/{model_file}")os.system(f"bzip2 -dk {model_file}")detector = dlib.get_frontal_face_detector()shape_predictor = dlib.shape_predictor(predictor_path)def detect_face_landmarks(img: Union[Image.Image, np.ndarray]):if isinstance(img, Image.Image):img = np.array(img)faces = []dets = detector(img)for d in dets:shape = shape_predictor(img, d)faces.append(np.array([[v.x, v.y] for v in shape.parts()]))return facesreturn detect_face_landmarksdef display_facial_landmarks(img: Image, landmarks: List[np.ndarray],fig_size=[15, 15]
):plot_style = dict(marker='o',markersize=4,linestyle='-',lw=2)pred_type = collections.namedtuple('prediction_type', ['slice', 'color'])pred_types = {'face': pred_type(slice(0, 17), (0.682, 0.780, 0.909, 0.5)),'eyebrow1': pred_type(slice(17, 22), (1.0, 0.498, 0.055, 0.4)),'eyebrow2': pred_type(slice(22, 27), (1.0, 0.498, 0.055, 0.4)),'nose': pred_type(slice(27, 31), (0.345, 0.239, 0.443, 0.4)),'nostril': pred_type(slice(31, 36), (0.345, 0.239, 0.443, 0.4)),'eye1': pred_type(slice(36, 42), (0.596, 0.875, 0.541, 0.3)),'eye2': pred_type(slice(42, 48), (0.596, 0.875, 0.541, 0.3)),'lips': pred_type(slice(48, 60), (0.596, 0.875, 0.541, 0.3)),'teeth': pred_type(slice(60, 68), (0.596, 0.875, 0.541, 0.4))}fig = plt.figure(figsize=fig_size)ax = fig.add_subplot(1, 1, 1)ax.imshow(img)ax.axis('off')for face in landmarks:for pred_type in pred_types.values():ax.plot(face[pred_type.slice, 0],face[pred_type.slice, 1],color=pred_type.color, **plot_style)plt.show()# https://github.com/NVlabs/ffhq-dataset/blob/master/download_ffhq.pyimport PIL.Image
import PIL.ImageFile
import numpy as np
import scipy.ndimagedef align_and_crop_face(img: Image.Image,landmarks: np.ndarray,expand: float = 1.0,output_size: int = 1024, transform_size: int = 4096,enable_padding: bool = True,
):# Parse landmarks.# pylint: disable=unused-variablelm = landmarkslm_chin          = lm[0  : 17]  # left-rightlm_eyebrow_left  = lm[17 : 22]  # left-rightlm_eyebrow_right = lm[22 : 27]  # left-rightlm_nose          = lm[27 : 31]  # top-downlm_nostrils      = lm[31 : 36]  # top-downlm_eye_left      = lm[36 : 42]  # left-clockwiselm_eye_right     = lm[42 : 48]  # left-clockwiselm_mouth_outer   = lm[48 : 60]  # left-clockwiselm_mouth_inner   = lm[60 : 68]  # left-clockwise# Calculate auxiliary vectors.eye_left     = np.mean(lm_eye_left, axis=0)eye_right    = np.mean(lm_eye_right, axis=0)eye_avg      = (eye_left + eye_right) * 0.5eye_to_eye   = eye_right - eye_leftmouth_left   = lm_mouth_outer[0]mouth_right  = lm_mouth_outer[6]mouth_avg    = (mouth_left + mouth_right) * 0.5eye_to_mouth = mouth_avg - eye_avg# Choose oriented crop rectangle.x = eye_to_eye - np.flipud(eye_to_mouth) * [-1, 1]x /= np.hypot(*x)x *= max(np.hypot(*eye_to_eye) * 2.0, np.hypot(*eye_to_mouth) * 1.8)x *= expandy = np.flipud(x) * [-1, 1]c = eye_avg + eye_to_mouth * 0.1quad = np.stack([c - x - y, c - x + y, c + x + y, c + x - y])qsize = np.hypot(*x) * 2# Shrink.shrink = int(np.floor(qsize / output_size * 0.5))if shrink > 1:rsize = (int(np.rint(float(img.size[0]) / shrink)), int(np.rint(float(img.size[1]) / shrink)))img = img.resize(rsize, PIL.Image.ANTIALIAS)quad /= shrinkqsize /= shrink# Crop.border = max(int(np.rint(qsize * 0.1)), 3)crop = (int(np.floor(min(quad[:,0]))), int(np.floor(min(quad[:,1]))), int(np.ceil(max(quad[:,0]))), int(np.ceil(max(quad[:,1]))))crop = (max(crop[0] - border, 0), max(crop[1] - border, 0), min(crop[2] + border, img.size[0]), min(crop[3] + border, img.size[1]))if crop[2] - crop[0] < img.size[0] or crop[3] - crop[1] < img.size[1]:img = img.crop(crop)quad -= crop[0:2]# Pad.pad = (int(np.floor(min(quad[:,0]))), int(np.floor(min(quad[:,1]))), int(np.ceil(max(quad[:,0]))), int(np.ceil(max(quad[:,1]))))pad = (max(-pad[0] + border, 0), max(-pad[1] + border, 0), max(pad[2] - img.size[0] + border, 0), max(pad[3] - img.size[1] + border, 0))if enable_padding and max(pad) > border - 4:pad = np.maximum(pad, int(np.rint(qsize * 0.3)))img = np.pad(np.float32(img), ((pad[1], pad[3]), (pad[0], pad[2]), (0, 0)), 'reflect')h, w, _ = img.shapey, x, _ = np.ogrid[:h, :w, :1]mask = np.maximum(1.0 - np.minimum(np.float32(x) / pad[0], np.float32(w-1-x) / pad[2]), 1.0 - np.minimum(np.float32(y) / pad[1], np.float32(h-1-y) / pad[3]))blur = qsize * 0.02img += (scipy.ndimage.gaussian_filter(img, [blur, blur, 0]) - img) * np.clip(mask * 3.0 + 1.0, 0.0, 1.0)img += (np.median(img, axis=(0,1)) - img) * np.clip(mask, 0.0, 1.0)img = PIL.Image.fromarray(np.uint8(np.clip(np.rint(img), 0, 255)), 'RGB')quad += pad[:2]# Transform.img = img.transform((transform_size, transform_size), PIL.Image.QUAD, (quad + 0.5).flatten(), PIL.Image.BILINEAR)if output_size < transform_size:img = img.resize((output_size, output_size), PIL.Image.ANTIALIAS)return img

第三段代码,设置图片导入方式(第一种网络读取图片,第二种本地加载),之后调用第二段中定义的算法,产生结果输出。

import requests# img = Image.open(requests.get("https://upload.wikimedia.org/wikipedia/commons/8/85/Elon_Musk_Royal_Society_%28crop1%29.jpg", stream=True).raw).convert("RGB")
img = Image.open(r"C:\Users\hp\Desktop\bidao.png").convert("RGB")face_detector = get_dlib_face_detector()
landmarks = face_detector(img)display_facial_landmarks(img, landmarks, fig_size=[5, 5])for landmark in landmarks:face = align_and_crop_face(img, landmark, expand=1.3)display(face2paint(model=model, img=face, size=512))

查看效果

好了,经历漫长和复杂的环境配置后,导入图片就能看到效果了。
我这里以毕导的图片为例:
原图:

人脸提取标注后:

动漫化对比:

结果非常Amazing啊!
不过,由于原图分辨率不高,动漫化好像并不彻底,比如耳朵部分仍保留着三次元特征,和真正的二次元还有点距离。

资源获取

本项目的文件我已打包放在了我的微信公众号“我有一计”上,回复“动漫”即可获取。

人脸动漫化——AnimeGAN快速上手相关推荐

  1. 人脸动漫化AnimeGAN V2的具体实施步骤

    本文提供应对课设,毕设的小伙伴们一些参考:项目是参照网络上比较火的一个项目AnimeGAN V2,然后当时的一个课题也是跟这个相关,然后我是直接调用这个的,但是中间遇到过很多的问题,现在想说明一些问题 ...

  2. 基于PaddleGAN项目人脸表情动作迁移学习(四)人脸动漫化

    学习目标: 体验基于PaddleGAN的真实人脸实现动漫化,相关模型:AnimeGANv2. AnimeGANv2原理: 人脸动漫化(Photo to Cartoon)是指将真实人脸转化成动漫风格,在 ...

  3. 阿里云视觉AI训练营_Class5_实践课:人脸动漫化搭建

    Class5 实践课:人脸动漫化搭建 学习目标: 10分钟开发一款"一键二次元化"AI小程序 学习内容: 5.1 10分钟开发一款"一键二次元化"AI小程序 注 ...

  4. animegan2实现人脸动漫化

    一.效果展示 (图片来源网络,如有侵权请联系删除) 二.技术摘要 1. 直接使用的animegan2自带的模型(https://github.com/bryandlee/animegan2-pytor ...

  5. 《Landmark Assisted CycleGAN for Cartoon Face Generation》人脸动漫化论文解析

    如何用真实的人脸照片生成卡通风格的头像呢?今天我们再来看看另一篇文章. 这篇文章来自香港中文大学+哈工大+腾讯优图.效果如下: 当然我写的前两篇文章,也是在说头像动漫化,是另外两个算法,各有千秋.传送 ...

  6. 阿里云趣味视觉AI训练营 实践 人脸动漫化搭建

    10分钟开发一款"一键二次元化"AI小程序 原标题是十分钟,搞了好长时间的 访问:https://workbench.aliyun.com/application/ 新建应用,通过 ...

  7. 阿里云人脸人体--人物动漫化效果

    原文链接:https://www.fearlazy.com/index.php/post/366.html 将照片动漫化一方面可以让人物变得更可爱,另一方面还能保护隐私.既实用又有趣. 先看看阿里云的 ...

  8. 【一文到底】【0基础】【快速上手】Django基本使用

    Django web开发 基础 1. Django的安装 和之前python一样,通过pip来安装即可 pip install django django和其他第三方Python模块一样,会在当前py ...

  9. K210快速上手教程(色块、人脸、声源识别等)

    k210实现各种功能快速上手 前言 开发环境以及材料准备 软件Maixpy IDE使用说明 识别色块并且串口输出最大色块中心坐标 声源方向的坐标识别 基于MicroPython的人脸识别 前言 最近想 ...

最新文章

  1. 使用正则表达式抽取新闻/BBS网页发表时间
  2. 基于HTML5 Canvas 实现矢量工控风机叶轮旋转
  3. GridView常用总结
  4. 可视化分析js的内存分配与回收
  5. 【耿老师公开课】反转!物联网火爆,开发者却很难入门?
  6. 修改pip安装源加快python模块安装
  7. 图解对比MySQL索引为什么要用B+树
  8. h5聊天页面 jquery_基于Jquery WeUI的微信开发H5页面控件的经验总结(1)
  9. jquery,字符串转json对象,json对象转字符串
  10. 服务器怎么支持smtp,如何搭建邮箱服务器,自建smtp服务器
  11. 蓝桥杯练习题(三):Python组之算法训练提高综合五十题
  12. coreldraw怎么打印荣誉证书_CorelDraw如何批量打印证书
  13. 用思维导图和孩子们一起了解“什么是春节”
  14. 蓝桥杯矩形切割python求解
  15. Axure 8.1.0.3377最新激活码
  16. mysql中limit2,1和limit2 offset 1的区别
  17. 糖豆人显示此服务器正在进行游戏,糖豆人神仙服务器
  18. 【FPGA实验2】二进制转为格雷码
  19. overleaf 写论文Latex语法记录
  20. 打开Steam VR,手柄图标却不显示(三星设备 连接蓝牙的)

热门文章

  1. jetson TX2挂载 256G sd卡
  2. 【截图工具】把图片钉在桌面上的截图工具——QQ截图、Snipaste
  3. python 电路仿真spice_SPICE的仿真电路图与现实到底有什么差距
  4. c 语言loadimage方法吗,CBitmap, HBITMAP和LoadImage
  5. MAC下,为什么下载ubuntu下载提示无课装载文件系统,下载很多版本,在官网上也下载了,请问如何解决
  6. 论文解读《SOLO: Segmenting Objects by Locations》
  7. 企业数字化转型之道--数字信号与模拟信号的区别
  8. 请各位大咖指点一下备考全国通信技术职业水平考试(初级)的考试经验
  9. ssm+JSP计算机毕业设计重庆工商大学公寓信息管理系统x49c1【源码、程序、数据库、部署】
  10. Python使用Selenium WebDriver的入门介绍及安装教程