关于python:用让新海诚本人惊讶的-AI-模型制作属于你的动漫视频

4次阅读

共计 17794 个字符,预计需要花费 45 分钟才能阅读完成。

本文将介绍如何应用 GAN 模型来生成属于你本人的动漫格调的视频,为本人、喜爱的菇凉或者淘气可恶孩子生成一个标新立异的动漫格调的视频。

本文操作难度较低,适宜想要试玩理解 GAN 模型的同学。能够同时应用 CPU / GPU(包含 ARM M1)来实现。

写在后面

这阵子在翻阅和学习一些模型相干的内容,当我看到赫赫有名的《你的名字》、《秒速五厘米》、《天气之子》等经典作品的导演新海诚,因为一组比照图收回了上面的感叹的时候,我的好奇心一下子就上来了。

图片中新海诚的感叹内容翻译过去的大略意思是:“很乏味,我感觉到了各种可能性。如果这是由美术工作人员提出的,电影将会重拍。笑”

在我看来,可能失去如新海诚这样的大佬翻牌子,或者这类模型值得一玩。于是,我试着用这类模型将我的结婚纪念视频进行了格调转换,发现成果还行啊。

接着,我又针对一些以往的照片试了试这个“滤镜”,发现针对局部照片来说,成果真的很不错。

独乐乐不如众乐乐,如果你也有打算为喜爱的人、或者孩子,甚至是本人做一些卡通风格化的视频 / 照片纪念的话,那么跟着我一起来折腾下本篇内容吧。

本篇将顺次介绍两种模型的应用,对于这两个模型的简略介绍,在本文结尾有提到,如果你感兴趣的话,能够跳转浏览。

好了,咱们先来进行一些筹备工作吧。

筹备工作

在开始为咱们的视频或者照片“加滤镜”之前,咱们须要先进行环境筹备。

本篇文章为了更简略一些,就不再在文章中开展如何进行模型的 Docker 镜像封装了,感兴趣的同学能够自行翻阅上篇《应用 Docker 来运行 HuggingFace 海量模型》文章内容,来学习相干内容。

应用 Conda 简化 Python 程序环境筹备工作

和上篇文章一样,我举荐应用 Conda 实现根底的程序运行环境的装置。

你能够从 Conda 官方网站下载适合的安装程序(安装包比拟大,大略 500M 左右,须要一些急躁)。

  • 如果你是 Mac x86 用户,能够下载 Anaconda3-2022.05-MacOSX-x86\_64.sh
  • 如果你是 Mac M1 用户,能够下载 Anaconda3-2022.05-MacOSX-arm64.sh
  • 如果你是 Linux 用户,能够下载 Anaconda3-2022.05-Linux-x86\_64.sh
  • 如果你是 Windows 用户,能够下载 Anaconda3-2022.05-Windows-x86\_64.exe

接下来,咱们先以 Mac 和 Ubuntu 为例,来演示如何实现环境的筹备。

从下面的地址下载好 Conda 安装文件之后,一行命令实现程序安装即可。

# 先进行 conda 的装置
bash Anaconda3-2022.05.(你的安装文件名称).sh 

如果你在应用 Ubuntu,和我一样,须要常常测试不同的模型和我的项目,能够在装置结束之后,执行上面的命令,让 conda shell 环境常驻。

# 在实现装置之后,能够思考 hi
eval "$(~/anaconda3/bin/conda shell.bash hook)"

至于 Mac,我更举荐什么时候应用,什么时候手动激活 conda shell。比方在装置结束 conda,并初始化好了某一个程序的专用环境之后,咱们能够通过执行 conda activate [环境名称] 命令来激活这个环境所须要的 shell。(对于如何初始化环境,请急躁往下看)

国内用户,举荐在应用 Conda 时,先进行软件源配置操作。这样能够缩小在下载软件包过程中造成的不必要工夫节约。

编辑 vi ~/.condarc 文件,在其中退出上面的内容(以“清华源”为例):

channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
  - defaults
show_channel_urls: true

当咱们实现了 ~/.condarc 的内容批改之后,先重启 Shell,接着应用 conda info 就能够查看软件源是否配置胜利了:

(base) soulteary@ubuntu:~# conda info

     active environment : base
...
           channel URLs : https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/linux-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/noarch
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/linux-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/linux-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/noarch
                          https://repo.anaconda.com/pkgs/main/linux-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/r/linux-64
                          https://repo.anaconda.com/pkgs/r/noarch
...

能够看到,日志输入中蕴含了咱们刚刚填写的“清华源”。

接下来,咱们来通过 conda 命令,来疾速创立咱们所须要的模型应用程序所须要的运行环境:

conda create -n my-anime-video python=3.10

下面的命令执行结束之后,将会创立一个名为 my-anime-video 的基于 Python 3.10 的根底运行环境;如果你须要其余版本的 Python 来运行本人的模型,能够调整命令中的版本号。

当环境创立结束之后,咱们须要先执行命令,将环境激活(用过 GVM、NVM 的同学应该会很相熟)。

conda activate my-anime-video

当环境激活之后,咱们的 shell 命令行提醒的开始处将会呈现这个环境名称提醒,通知咱们当初正位于这个环境之下:

(my-anime-video) # your shell command here...

当实现环境激活之后,咱们同样先来实现软件源的切换(上篇文章有具体介绍,感兴趣能够自行浏览):

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

接着来实现 PyTorch 罕用依赖的装置:

pip install torch torchvision torchaudio 

最初装置一个用来“偷懒”的工具 Towhee

pip install towhee

至于这个工具能省多小事,我先卖个关子不提,看到前面你就晓得了。

装置 ffmpeg 来解决多媒体素材

如果你只是心愿解决图片,那么这部分能够跳过,如果你心愿解决的内容蕴含视频,咱们须要借助 ffmpeg 这个工具的力量。

在 macOS 中,咱们能够通过 brew 来进行装置:

brew install ffmpeg

在 Linux 环境中,比方 Ubuntu,咱们能够通过 apt 来进行装置:

apt install ffmpeg -y

在 ffmpeg 装置就绪之后,咱们来针对视频进行解决,将视频转换为待处理的图片。

比方,咱们要将当前目录的视频 wedding-video.mp4 依照每秒 25 帧拆解为图片,并将图片保留在当前目录的 images 目录下,能够执行上面的命令:

ffmpeg -i ./wedding-video.mp4 -vf fps=25 images/video%d.png

当命令执行结束之后,咱们将失去满满一个文件夹的图片,它们都将以命令中的 video 为前缀,数字为结尾。我抉择的视频文件靠近 15 分钟,当转换结束之后,失去了两万多张图片。

ls images/| wc -l
21628

当下面的筹备工作都就绪之后,咱们来看看如何应用两种模型来生成属于咱们本人的卡通 / 动漫格调的视频。

先来看看第一个模型:CartoonGAN

CartoonGAN

对于这个模型,我找到了一个 HuggingFace 上的在线试玩地址:https://huggingface.co/spaces/akiyamasho/AnimeBackgroundGAN。

这个在线工具来自一位日本开发者,在它的另外一个我的项目 AnimeBackgroundGAN-Shinkai(新海诚格调)中,咱们可能找到一个预训练模型(关联我的项目中还有宫崎骏、细田守、今敏的格调),而在 GitHub 中,咱们可能找到这个我的项目对应的代码仓库 venture-anime/anime-background-gan-hf-space。

在进行上文提到的视频素材(大量图片)解决之前,咱们先来试着在本地运行起来一个同款的 Web 工具,来验证模型代码是否可能正确运行。

验证我的项目模型成果

这个我的项目能够应用 CPU 或 GPU 运行,如果你手头有 macOS、Ubuntu 的话,能够间接运行。

不过原始我的项目对于最新版本的 PyTorch 反对有一些问题,应用 GPU 运行会报错,并且不反对指定显卡运行,以及我的项目依赖有一些问题,所以我做了一个 fork 版本:https://github.com/soulteary/anime-background-gan-hf-space。

咱们应用 Git 下载我的项目,而后切换到我的项目目录中:

git clone https://github.com/soulteary/anime-background-gan-hf-space.git
cd anime-background-gan-hf-space

在进一步进行之前,咱们须要确认曾经用 conda 将之前筹备的 Python 环境激活,如果你不确定或者还没有进行切换,能够再次执行上面的命令(反复执行没有副作用):

conda activate my-anime-video

在切换到 my-anime-video 这个环境之后,咱们应用 Python 启动我的项目:

python app.py

在命令执行之后(可能须要稍等片刻),咱们将失去相似上面的日志:

/Users/soulteary/anaconda3/envs/my-anime-video/lib/python3.10/site-packages/gradio/deprecation.py:40: UserWarning: `optional` parameter is deprecated, and it has no effect
  warnings.warn(value)
Running on local URL:  http://127.0.0.1:7860/

To create a public link, set `share=True` in `launch()`.

而后关上浏览器,输出下面日志中提醒的地址 http://127.0.0.1:7860/,就可能看到一个在线的 Web 工具界面啦。

要进行模型和利用代码验证也很简略,点击右边的图片上传区域,上传一个你想要测试的图片,而后点击“提交”即可。

能够看到,一张颇有卡通感的图片呈现在了右侧。这里如果应用 CPU 运行,个别须要 3~10s 来解决一张图,如果应用 GPU,则个别须要 1s 左右。

在实现了程序和模型的验证之后,咱们来编写批量解决图片的程序。

编写模型调用程序进行批量图片解决

残缺程序,我曾经上传到了 GitHub https://github.com/soulteary/have-fun-with-AnimeGAN/blob/main/CartoonGAN/app.py 不便大家自取。

原始的我的项目中,并不反对批量读取图片,并且默认会加载四个模型,比拟浪费资源,所以我这里进行了一些功能完善。

import argparse
import glob, os
import time
from pathlib import Path
from PIL import Image

import torch
import numpy as np
import torchvision.transforms as transforms
from torch.autograd import Variable
from network.Transformer import Transformer
from huggingface_hub import hf_hub_download

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def parse_args():
    desc = "CartoonGAN CLI by soulteary"
    parser = argparse.ArgumentParser(description=desc)
    parser.add_argument('--model', type=str, default='Shinkai', help='Shinkai / Hosoda / Miyazaki / Kon')
    parser.add_argument('--input', type=str, default='./images', help='images directory')
    parser.add_argument('--output', type=str, default='./result/', help='output path')
    parser.add_argument('--resize', type=int, default=0,
                        help='Do you need a program to adjust the image size?')
    parser.add_argument('--maxsize', type=int, default=0,
                        help='your desired image output size')
    """If you want to resize, you need to specify both --resize and --maxsize"""
    return parser.parse_args()

def prepare_dirs(path):
    Path(path).mkdir(parents=True, exist_ok=True)


arg = parse_args()


enable_gpu = torch.cuda.is_available()

if enable_gpu:
    # If you have multiple cards,
    # you can assign to a specific card, eg: "cuda:0"("cuda") or "cuda:1"
    # Use the first card by default: "cuda"
    device = torch.device("cuda")
else:
    device = "cpu"

def get_model(style):
    # Makoto Shinkai
    if style == "Shinkai":
        MODEL_REPO_SHINKAI = "akiyamasho/AnimeBackgroundGAN-Shinkai"
        MODEL_FILE_SHINKAI = "shinkai_makoto.pth"
        model_hfhub = hf_hub_download(repo_id=MODEL_REPO_SHINKAI, filename=MODEL_FILE_SHINKAI)
    # Mamoru Hosoda
    elif style == "Hosoda":
        MODEL_REPO_HOSODA = "akiyamasho/AnimeBackgroundGAN-Hosoda"
        MODEL_FILE_HOSODA = "hosoda_mamoru.pth"
        model_hfhub = hf_hub_download(repo_id=MODEL_REPO_HOSODA, filename=MODEL_FILE_HOSODA)
    # Hayao Miyazaki
    elif style == "Miyazaki":
        MODEL_REPO_MIYAZAKI = "akiyamasho/AnimeBackgroundGAN-Miyazaki"
        MODEL_FILE_MIYAZAKI = "miyazaki_hayao.pth"
        model_hfhub = hf_hub_download(repo_id=MODEL_REPO_MIYAZAKI, filename=MODEL_FILE_MIYAZAKI)
    # Satoshi Kon
    elif style == "Kon":
        MODEL_REPO_KON = "akiyamasho/AnimeBackgroundGAN-Kon"
        MODEL_FILE_KON = "kon_satoshi.pth"
        model_hfhub = hf_hub_download(repo_id=MODEL_REPO_KON, filename=MODEL_FILE_KON)

    model = Transformer()
    model.load_state_dict(torch.load(model_hfhub, device))
    if enable_gpu:
        model = model.to(device)
    model.eval()
    return model

def inference(img, model):
    # load image
    input_image = img.convert("RGB")
    input_image = np.asarray(input_image)
    # RGB -> BGR
    input_image = input_image[:, :, [2, 1, 0]]
    input_image = transforms.ToTensor()(input_image).unsqueeze(0)
    # preprocess, (-1, 1)
    input_image = -1 + 2 * input_image

    if enable_gpu:
        logger.info(f"CUDA found. Using GPU.")
        # Allows to specify a card for calculation
        input_image = Variable(input_image).to(device)
    else:
        logger.info(f"CUDA not found. Using CPU.")
        input_image = Variable(input_image).float()

    # forward
    output_image = model(input_image)
    output_image = output_image[0]
    # BGR -> RGB
    output_image = output_image[[2, 1, 0], :, :]
    output_image = output_image.data.cpu().float() * 0.5 + 0.5

    return transforms.ToPILImage()(output_image)


prepare_dirs(arg.output)

model = get_model(arg.model)

enable_resize = False
max_dimensions = -1
if arg.maxsize > 0:
    max_dimensions = arg.maxsize
    if arg.resize :
        enable_resize = True

globPattern = arg.input + "/*.png"

for filePath in glob.glob(globPattern):
    basename = os.path.basename(filePath)
    with Image.open(filePath) as img:
        if(enable_resize):
            img.thumbnail((max_dimensions, max_dimensions), Image.Resampling.LANCZOS)

        start_time = time.time()
        inference(img, model).save(arg.output + "/" + basename, "PNG")
        print("--- %s seconds ---" % (time.time() - start_time))

下面这段一百来行的程序大略做了这么几件事,会依据传递参数来动静的载入必要的模型,而不是所有的模型。默认状况下,它会读取当前目录 images 子目录的所有图片,并顺次调用 CPU / GPU 来进行图片解决,并将处理结果保留在 result 子目录中。如果你心愿对输入图片进行尺寸调整,能够传递参数来做限度。

咱们来试着运行下这个程序:

python app.py --model=Shinkai

当命令开始执行后,咱们就可能批量解决视频图片啦,如果不出意外,你将会看到相似上面的日志:

...
--- 1.5597078800201416 seconds ---
INFO:__main__:Image Height: 1080, Image Width: 1920
--- 0.44031572341918945 seconds ---
INFO:__main__:Image Height: 1080, Image Width: 1920
--- 1.5004260540008545 seconds ---
INFO:__main__:Image Height: 1080, Image Width: 1920
--- 1.510758876800537 seconds ---
INFO:__main__:Image Height: 1080, Image Width: 1920
--- 1.362170696258545 seconds ---
INFO:__main__:Image Height: 1080, Image Width: 1920
...

这里须要解决的工夫可能会比拟久,如果咱们有 GPU 会极大的晋升速度,或者适当调整输入图片的大小,也可能在应用 CPU 进行渲染的状况下,失去比拟快的处理速度。

当程序运行完结之后,咱们在 result 目录中,就可能失去通过 AI 模型解决的图片内容了,这时咱们只有再次应用 ffmpeg 将图片转换为视频就好啦:

ffmpeg -f image2 -r 25 -i result/video%d.jpg -vcodec libx264 -crf 18  -pix_fmt yuv420p result.mp4

接下来,咱们先来聊聊如何应用 GPU 进行提速,而后再来看看有没有更通用的、低成本的提速计划。

应用 GPU 进行模型执行提速

如果你没有 GPU,想用最小老本来玩,那么能够间接浏览下一大节内容。

言归正传,假如咱们要解决上万甚至十万张图片,最好的形式便是应用 GPU 进行数据处理。思考到以后一块能高效跑 AI 模型的具备大显存的显卡至多一万起步,我更举荐应用按量付费的云主机,大略每小时 10~20 块钱,跑个个把小时,就能拿到你想要的后果啦。我集体测试下来,几个云厂商带有显卡的主机都差不多,大家依据本人状况和喜爱的形式抉择就行,如果是学生身份,或者有些平台还能有教育折扣。

为了可能绝对疾速的失去后果,我抉择了一台双卡云主机,在不做程序的深度优化前,可能间接让数据处理工夫减半。

想要让两张显卡各解决一半的数据,咱们能够抉择批改下面的程序,也能够用 Linux Shell 把数据间接分为两堆儿。作为一个懒人,咱们抉择后者。(如果你只有一张卡,能够跳过这个步骤)

先来确认以后待处理的数据总量,有两万多张图片。

ls images/| wc -l
21628

接着应用组合命令,将一半的图片挪到新创建的文件夹中:

mkdir images2
ls | sort | head -10814 | xargs -I {} mv {} images2/

在筹备完数据之后,咱们同样须要对程序做一点小的调整,让程序别离应用两张不同的显卡设施,咱们能够抉择像程序读取输入输出文件夹应用参数雷同的形式,来让用户指定显卡设施;也能够抉择更简略的形式,将下面的程序复制一份,调整原来的程序和新程序中要调用的显卡设施名称,比方,将 device = torch.device("cuda") 调整为 device = torch.device("cuda:0")device = torch.device("cuda:1")

当实现上述调整和筹备之后,别离应用 python 执行两个程序即可:python app1.pypython app2.py。如果你不能保障你通过 SSH 连贯到服务器的会话稳固,那么能够试试应用 screentmux 这类工具。

程序开始运行之后,接下来就是漫长的期待,在处理过程中,咱们能够应用 nvidia-smi 查看显卡状态,能够看到如果这台“电脑”搁家里,应该是蛮费电的,而且大概率会很吵。

nvidia-smi 

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.102.04   Driver Version: 450.102.04   CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000000:00:08.0 Off |                    0 |
| N/A   54C    P0   263W / 300W |  25365MiB / 32510MiB |    100%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-SXM2...  On   | 00000000:00:09.0 Off |                    0 |
| N/A   55C    P0   265W / 300W |  25365MiB / 32510MiB |    100%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A     61933      C   python                          25363MiB |
|    1   N/A  N/A     62081      C   python                          25363MiB |
+-----------------------------------------------------------------------------+

当程序处理完所有图片之后,会主动退出。这个时候,咱们能够再次应用 ffmpeg 将图片还原为视频:

time ffmpeg -f image2 -r 25 -i result/video%d.png -vcodec libx264 -crf 18  -pix_fmt yuv420p result.mp4

当程序运行结束,咱们将看到相似上面的日志:

Output #0, mp4, to 'result.mp4':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1920x1080, q=-1--1, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=21628 fps= 75 q=-1.0 Lsize= 1135449kB time=00:14:25.00 bitrate=10753.3kbits/s speed=2.99x    
video:1135185kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.023257%
[libx264 @ 0x55779059b380] frame I:253   Avg QP:15.48  size:194386
[libx264 @ 0x55779059b380] frame P:6147  Avg QP:17.74  size: 95962
[libx264 @ 0x55779059b380] frame B:15228 Avg QP:20.43  size: 34369
[libx264 @ 0x55779059b380] consecutive B-frames:  4.7%  2.9%  4.0% 88.4%
[libx264 @ 0x55779059b380] mb I  I16..4: 16.0% 47.1% 36.9%
[libx264 @ 0x55779059b380] mb P  I16..4:  7.9% 13.9%  6.1%  P16..4: 31.2% 18.5%  9.3%  0.0%  0.0%    skip:13.0%
[libx264 @ 0x55779059b380] mb B  I16..4:  1.6%  1.6%  0.5%  B16..8: 34.3%  9.6%  2.7%  direct:11.8%  skip:37.9%  L0:42.2% L1:42.3% BI:15.5%
[libx264 @ 0x55779059b380] 8x8 transform intra:48.1% inter:59.5%
[libx264 @ 0x55779059b380] coded y,uvDC,uvAC intra: 47.2% 66.3% 35.9% inter: 30.7% 35.6% 1.6%
[libx264 @ 0x55779059b380] i16 v,h,dc,p: 39% 32%  6% 23%
[libx264 @ 0x55779059b380] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 27% 20% 26%  4%  5%  4%  5%  4%  5%
[libx264 @ 0x55779059b380] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 33% 20% 16%  5%  6%  6%  5%  5%  4%
[libx264 @ 0x55779059b380] i8c dc,h,v,p: 50% 21% 21%  8%
[libx264 @ 0x55779059b380] Weighted P-Frames: Y:24.2% UV:17.1%
[libx264 @ 0x55779059b380] ref P L0: 49.1% 14.5% 22.1% 12.4%  1.9%
[libx264 @ 0x55779059b380] ref B L0: 81.3% 14.0%  4.7%
[libx264 @ 0x55779059b380] ref B L1: 93.6%  6.4%
[libx264 @ 0x55779059b380] kb/s:10749.30

real    4m49.667s
user    78m36.497s
sys    0m44.806s

当我关上处理完毕的视频,就集体观感而言,光线短缺的场景下,模型的施展还是比拟好的。这里因为上传图片压缩,成果没有本地看到的惊艳,感兴趣的同学无妨试试。

或者你想晓得,有没有什么不必 GPU 也能进行一些减速成果的计划呢?答案是有的。

应用并行计算和流式解决来减速图片解决

Python 3 反对 concurrent API,来做并行计算。不过解决并发计算,个别还须要折腾队列,波及到多线程调度,波及到流式 IO 等等一坨麻烦事。而且并发代码调试也比拟恶心,尤其是在 Python 中 …(个人观点)

还记得我在上文中已经 pip installtowhee 么,这个软件包里蕴含了一些快捷的工具办法,可能简化下面一系列麻烦事件,让咱们解决雷同的事件,花更少的代价,因为很多时候,一些根本的带有复杂度的麻烦事,应该交给根底工具来解决,而不是都由开发者吭哧吭哧的填。

咱们以上文中一百多行的模型利用代码举例,如果换用 Towhee 做一个“平替”程序,那么能够这样来实现:

import towhee

towhee.glob('./*.png') \
    .image_decode() \
    .img2img_translation.cartoongan(model_name = 'Shikai') \
    .save_image(dir='./result')
    .to_list()

几行代码,就实现了外围逻辑:批量读取图片、将图片进行 RGB 编码转换,而后将图片数据传递给模型进行解决,最初进行模型计算结果保留到某个文件夹里。

接下来,咱们再对下面的代码进行一些调整,来实现下面提到的麻烦事,并行计算。其实须要的改变很少,只须要咱们在“解决图片编码转换”之前,加上一行 .set_parallel(5) 来通知程序,咱们要应用多个线程来搞事件就行啦。

当程序运行起来的时候,就会默认调用 5 个并发来执行计算,所以即便没有 GPU,只应用 CPU 的状况下,咱们也可能获取更高的执行效率。

import towhee

towhee.glob('./*.png') \
    .set_parallel(5) \
    .image_decode() \
    .img2img_translation.cartoongan(model_name = 'Shikai') \
    .save_image(dir='./result')
    .to_list()

在玩 Towhee 的过程中,我也遇到了一些小问题。比方 Towhee 这个工具的设计初衷是为了科学计算,所以像是保留图片、折腾视频文件都不是它的主业,默认状况下,它会以 UUID 的模式来保留解决后的图片。

为了可能让图片后果为咱们所用,输入的图片可能依照原始文件名称进行存储,让模型解决完的后果可能“还原成视频”。我特地向它的开源仓库提交了一个 PR(\#1293)来解决这个问题。

当然,咱们也须要对下面的几行代码做一些额定的调整,增加一些参数:

import towhee

towhee.glob['path']("./*.png") \
    .set_parallel(5) \
    .image_decode['path','img']() \
    .img2img_translation.cartoongan['img', 'img_new'](model_name = "Shikai") \
    .save_image[('img_new','path'), 'new_path'](dir="./result") \
    .to_list()

不过,截止本文公布的时候,蕴含我的 PR 的骨干版本,还没有被正式公布,所以临时还须要装置 Python PyPI 每日构建的开发版的软件包来应用这个性能。

pip install -i https://test.pypi.org/simple/ towhee==0.6.2.dev48

如果大家感觉这个偷懒的玩法还不错,能够代我去官网开源仓库去提 Issue,催催保护团队更新版本。

那么,为啥作为 Towhee 用户的我不去催呢?其实是因为不好意思。为啥不好意思呢?你接着看上来就晓得啦。

AnimeGAN

在聊完 CartoonGAN 之后,咱们来试试另外一个模型:AnimeGAN。目前模型有三个版本,除了第三个版本外,都是收费应用的开源我的项目。

为了不便演示以及一些特地的起因(文末详述),我这里抉择开源且较为稳固的第二个版本。

在开始折腾之前,同样也能够先试试它的在线试玩的 Demo:https://huggingface.co/spaces/akhaliq/AnimeGANv2。

还是先来进行本地我的项目验证,来验证模型代码是否可能正确运行。

验证我的项目模型成果

思考到文章篇幅和工程师“美德”(偷懒),咱们就不再折腾简短的模型调用程序代码了,我抉择持续用 Python 版“jQuery”来“Write Less, Do More”:

import towhee

arg = parse_args()
towhee.glob['path']("./*.png") \
    .set_parallel(5) \
    .image_decode['path', 'img']() \
    .img2img_translation.animegan['img', 'new_img'](model_name ="Shinkai") \
    .save_image[('new_img', 'path'), 'new_path'](dir="./result", format="png") \
    .to_list()

逻辑和上文中调用 CartoonGAN 一样,惟一的差异是应用了 animegan 的模型。

咱们将下面的代码保留为 lazy.py,而后从网上轻易找些图片放在程序所在的目录,执行 python lazy.py,稍等片刻就可能在程序同级目录发现一个新的名为 result 的文件夹,外面放着的就是咱们用模型解决过的图片啦。

相干代码,我曾经上传到了 https://github.com/soulteary/have-fun-with-AnimeGAN/blob/main/AnimeGAN/lazy.py 感兴趣的同学能够自取。

在验证结束模型成果之后,咱们同样能够应用这个模型来生成一段卡通格调的视频。

尽管上文中应用 ffmpeg 拼合视频的效率十分高,然而毕竟要执行额定的两条命令,有没有什么方法能够进一步偷懒呢?答案显然是有的。

编写模型调用程序进行视频解决

不晓得是否还有同学记得,在上篇文章中我提到的 Towhee 外围开发者之一的 @候杰 同学。在我死缠烂打之下,他帮我这个 Python 菜鸟,搞了一个 read_video 办法。

所以,上文中须要先用 ffmpeg 把视频转换为图片,而后在模型解决之后,再把图片拼合成视频的繁琐操作,就能够被几行代码代替掉啦!相比拟之前的玩法,新的代码行数霎时缩短到了五行左右(算空行也就六行),节约了本来须要写的 80% 的代码行数。

import towhee

towhee.read_video("./video.mp4") \
    .set_parallel(5) \
    .img2img_translation.animegan['img', 'new_img'](model_name = 'Skinkai') \
    .to_video('./result.mp4', 'x264', 15)

下面这几行代码执行下来,别离会主动套用模型解决视频的每一帧内容,而后将模型处理结果从新编码为每秒 15 帧的视频文件。理论应用的时候,你能够依据本人的需要进行码率调整。

为了不便你的应用,我也将代码上传到了 GitHub,须要的同学能够自取。

针对视频文件进行疾速预览

相比拟图片内容解决,雷同分辨率的视频的数据量其实会大不少。

所以如果咱们想对视频进行一个疾速成果预览,能够思考在代码中增加一个尺寸调整的性能,将每一帧须要解决的图片尺寸进行缩放,缩小计算量。

一如上文中的偷懒准则,想要搞定这个“需要”的办法也很简略,只须要加一行 image_resize 在适合的地位:

import towhee

towhee.read_video("./video.mp4") \
    .set_parallel(5) \
    .image_resize(fx=0.2, fy=0.2) \
    .img2img_translation.animegan['img', 'new_img'](model_name = 'Skinkai') \
    .to_video('./result.mp4', 'x264', 15)

这部分的代码,我仍旧上传到了 GitHub,心愿对你有帮忙。

其余

好啦!到这里为止,我曾经讲完了:

  • 如何筹备一个疾速上手的 Python 环境
  • 如何疾速上手应用 CartoonGAN、AnimeGAN 两个模型;
  • 如何用这两个模型解决图片或者视频;
  • 如何应用 Python 模型里的“jQuery”:Towhee 来偷懒,少写代码多搞事件。
  • 如何进行 GitHub 上“家养”模型我的项目的根本调优和封装

接下来,咱们来简略聊聊文章结尾提到的模型。

对于 AnimeGAN 和 CartoonGAN

对于应用 GAN(生成反抗网络)模型来对图片做动漫卡通风格化处理,就国内而言,目前有两个知名度较高的国产我的项目。

一个是来自清华大学团队在 2018 年公开的 CartoonGAN,该模型的论文当选 CVPR 2018,在 GitHub 上有 700 余颗星星。另外一个是来自湖北科技大学,在 2019 年公开的 AnimeGAN,该模型至今已迭代了三个版本(前两个版本开源),并在 GitHub 上累计播种了近 8 千颗星星。

对于两个模型和论文,媒体都曾进行过报道宣传:《实景照片秒变新海诚格调漫画:清华大学提出 CartoonGAN》、《强烈安利试试这个!成果爆炸的漫画变身 AI,火到服务器几度挤爆》,其中 AnimeGAN 解决的图片后果,甚至失去了新海诚的感叹。

我集体应用下来,CartoonGAN 和 AnimeGAN 各有劣势和有余,至于模型成果,以及各自适宜哪些场景。置信聪慧的读者们,能够通过本文提到的形式,和本人的实际来找到答案。

这两个我的项目的开源仓库地址:

  • https://github.com/mnicnc404/CartoonGan-tensorflow / 模型下载:http://cg.cs.tsinghua.edu.cn/people/\~Yongjin/CartoonGAN-Models.rar
  • https://github.com/TachibanaYoshino/AnimeGAN
  • https://github.com/TachibanaYoshino/AnimeGANv2

目前,因为 AnimeGAN v3 正在进行商业化尝试,并且是闭源公布,为了不对作者造成影响,这里就先不做相干模型封装和尝试啦。

开源不易,模型我的项目开源尤为不易,可能做商业化转型更是不易,须要社区、须要国人同胞的反对和激励。只有一直反对和反馈开源生态,国内的开源生态才有可能向好的方向变动,而当生态变好之时,咱们这些从业者定然可能从中取得更多的好处。

最初

在一周前,我在朋友圈晒过应用模型来解决之前结婚的留念视频,有不少敌人点赞和示意好奇如何“折腾本人的照片或视频”,过后承诺大家会出一篇教程,趁着端午节,赶出了这篇内容,心愿大家玩的欢快。

最初,再次感激被我死缠烂打之下增加了新性能的 @侯杰 同学,同样感激为我的 PR 提供了大量倡议,帮忙我把模型传递到 Towhee Hub,解决国内下载模型迟缓问题的、来自彩云之南的程序媛 @室余 妹纸。

–EOF


本文应用「署名 4.0 国内 (CC BY 4.0)」许可协定,欢送转载、或从新批改应用,但须要注明起源。署名 4.0 国内 (CC BY 4.0)

本文作者: 苏洋

创立工夫: 2022 年 06 月 04 日
统计字数: 20370 字
浏览工夫: 41 分钟浏览
本文链接: https://soulteary.io/2022/06/…

正文完
 0