本文将介绍如何应用 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 环境常驻。

# 在实现装置之后,能够思考hieval "$(~/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/  - defaultsshow_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 -l21628

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

先来看看第一个模型: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.gitcd 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 argparseimport glob, osimport timefrom pathlib import Pathfrom PIL import Imageimport torchimport numpy as npimport torchvision.transforms as transformsfrom torch.autograd import Variablefrom network.Transformer import Transformerfrom huggingface_hub import hf_hub_downloadimport logginglogging.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 modeldef 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 = Falsemax_dimensions = -1if arg.maxsize > 0:    max_dimensions = arg.maxsize    if arg.resize :        enable_resize = TrueglobPattern = 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 -l21628

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

mkdir images2ls | 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: -1frame=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.30real    4m49.667suser    78m36.497ssys    0m44.806s

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

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

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

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

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

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

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

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

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

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

import towheetowhee.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 towheetowhee.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 towheearg = 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 towheetowhee.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 towheetowhee.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/...