神工鬼斧惟肖惟妙,M1 mac系統深度學習框架Pytorch的二次元動漫動畫風格遷移濾鏡AnimeGANv2+Ffmpeg(圖片+視訊)快速實踐

語言: CN / TW / HK

原文轉載自「劉悅的技術部落格」https://v3u.cn/a_id_201

前段時間,業界鼎鼎有名的動漫風格轉化濾鏡庫AnimeGAN釋出了最新的v2版本,一時間街談巷議,風頭無兩。提起二次元,目前國內使用者基數最大的無疑是抖音客戶端,其內建的一款動畫轉換濾鏡“變身漫畫”,能夠讓使用者在直播中,把自己的實際外貌轉換為二次元“畫風”。對於二次元粉絲來說,“打破次元壁,變身紙片人”這種自娛自樂方式可謂屢試不爽:

但是看多了就難免有些審美疲勞,千人一面的“錐子臉”,一成不變的“卡姿蘭”式大眼睛,讓人多少有點味同嚼蠟的感覺,未免過猶不及,失之現實。

而基於CartoonGan的AnimeGAN動漫風格濾鏡則能夠在保留原圖特點的同時,兼具二次元的炫酷和三次元的寫實,頗有些剛柔並濟、舉重若輕的感覺:

並且AnimeGAN專案組業已在線上釋出demo介面,可以直接執行模型效果:https://huggingface.co/spaces/akhaliq/AnimeGANv2 但是受限於頻寬以及線上資源瓶頸,線上遷移佇列經常會處於排隊的狀態,同時一些原圖的上傳也可能造成個人隱私的外洩。

所以本次我們在M1晶片的Mac os Monterey基於Pytorch深度學習框架,本地搭建AnimeGANV2版本的靜態圖片以及動態視訊的轉化服務。

我們知道,目前Pytorch的cpu版本在M1晶片mac上的支援版本是Python3.8,在之前的一篇文章中:金玉良緣易配而木石前盟難得|M1 Mac os(Apple Silicon)天生一對Python3開發環境搭建(整合深度學習框架Tensorflow/Pytorch),曾經使用condaforge來構建Pytorch的開發環境,這次我們使用原生的安裝包進行安裝,首先進入Python官網,下載 Python3.8.10 universal2 穩定版 :https://www.python.org/downloads/release/python-3810/

雙擊安裝即可,隨後進入終端鍵入命令安裝Pytorch:

pip3.8 install torch torchvision torchaudio

這裡我們預設安裝最新的穩定版1.10,隨後進入Python3.8命令列,匯入torch庫:

``` (base) ➜ video git:(main) ✗ python3.8
Python 3.8.10 (v3.8.10:3d8993a744, May 3 2021, 09:09:08)
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

import torch

```

確定Pytorch可以使用之後,將官方專案克隆下來:

git clone https://github.com/bryandlee/animegan2-pytorch.git

AnimeGAN也是基於生成對抗網路(Generative adversarial network),原理就是我們手上有一定量的原圖,我們可以稱之為三次元圖片,真實的圖片特徵會存在一個分佈,比如:正態分佈,均勻分佈,或者更為複雜的分佈形式,那麼GAN的目的是通過生成器來生成一批與真實分佈接近的資料。這些資料可以理解為二次元的優化,但是會保留三次元的一些特徵,比如說眼睛變大、臉型更接近濾鏡模型的畫風等等,在我們的處理中,這個生成器趨向於使用神經網路,因為它能表示更為複雜的資料分佈情況。

下載成功之後,可以在weights資料夾下看到四種不同的權重模型,其中celeba_distill.pt和paprika.pt是用來轉化風景圖片的,而face_paint_512_v1.pt和face_paint_512_v2.pt則更注重於肖像的轉化。

首先安裝影象處理庫Pillow:

pip3.8 install Pillow

隨後新建test_img.py檔案:

``from PIL import Image
import torch
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="celeba_distill")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v1")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v2")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="paprika")

face2paint = torch.hub.load("bryandlee/animegan2-pytorch:main", "face2paint", size=512)

img = Image.open("Arc.jpg").convert("RGB")``out = face2paint(model, img)

out.show()` ```

這裡以凱旋門的照片為例子,分別使用celeba_distill和paprika濾鏡檢視效果,注意本地請求需要關閉ssl證書檢測,同時首次執行需要下載線上模型引數:

這裡影象尺寸引數指的是寬高通道的總數,接下來就是人物肖像動漫風格轉化了,調整匯入的模型生成器型別,輸入圖片改成人物肖像:

``` from PIL import Image
import torch
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

import numpy as np

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="celeba_distill")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v1")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v2")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="paprika")

face2paint = torch.hub.load("bryandlee/animegan2-pytorch:main", "face2paint", size=512)

img = Image.open("11.png").convert("RGB")

out = face2paint(model, img)

out.show() ```

可以看到,v1濾鏡相對風格化更強烈一些,而v2在風格化的基礎上相對保留了原圖的特徵,源於三次元又不拘泥於體驗,架空卻又不流於虛浮,比抖音的漫畫濾鏡不知道高到哪裡去了。

下面我們來看看動態視訊的動漫濾鏡轉換,視訊從廣義上來講,就是多張圖片的連拍播放,只不過取決於視訊幀的速率問題,幀速率也稱為FPS(Frames PerSecond)的縮寫——幀/秒,是指每秒鐘重新整理的圖片的幀數,也可以理解為圖形處理器每秒鐘能夠重新整理幾次。 越高的幀速率可以得到更流暢、更逼真的動畫,每秒鐘幀數(FPS)越多,所顯示的動作就會越流暢。

這裡可以通過第三方軟體將連貫的視訊轉換為以FPS為單位的圖片,在m1 mac os系統中,推薦使用著名的視訊處理軟體:Ffmpeg

使用arm架構的Homebrew進行安裝:

brew install ffmpeg

安裝成功後,在終端鍵入ffmpeg命令檢視版本:

(base) ➜ animegan2-pytorch git:(main) ✗ ffmpeg ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers built with Apple clang version 13.0.0 (clang-1300.0.29.3) configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/4.4.1_3 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox

安裝沒有問題,隨後準備一個視訊檔案,新建 video_img.py:

``` import os

視訊轉圖片

os.system("ffmpeg -i ./視訊.mp4 -r 15 -s 1280,720 -ss 00:00:20 -to 00:00:22 ./myvideo/%03d.png") ```

這裡我們使用Python3內建的os模組直接執行ffmpeg命令,針對當前目錄的視訊,以每秒15幀的速率進行轉化,-s引數代表視訊解析度,-ss引數可以控制視訊的開始位置和結束位置,最後是匯出圖片的目錄。

執行指令碼之後,進入myvideo目錄:

(base) ➜ animegan2-pytorch git:(main) ✗ cd myvideo (base) ➜ myvideo git:(main) ✗ ls 001.png 004.png 007.png 010.png 013.png 016.png 019.png 022.png 025.png 028.png 002.png 005.png 008.png 011.png 014.png 017.png 020.png 023.png 026.png 029.png 003.png 006.png 009.png 012.png 015.png 018.png 021.png 024.png 027.png 030.png (base) ➜ myvideo git:(main) ✗

可以看到,圖片按照幀數作為下標檔名已經轉換完畢。

接著需要利用AnimeGAN濾鏡對圖片進行批量轉換:

``` from PIL import Image
import torch
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

import numpy as np

import os

img_list = os.listdir("./myvideo/")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="celeba_distill")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v1")

model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="face_paint_512_v2")

#model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="paprika")

face2paint = torch.hub.load("bryandlee/animegan2-pytorch:main", "face2paint", size=512)

for x in img_list:

if os.path.splitext(x)[-1] == ".png":

    print(x)

    img = Image.open("./myvideo/"+x).convert("RGB")

    out = face2paint(model, img)

    out.show()  
    out.save("./myimg/"+x)

    # exit(-1)

```

每一次轉換都將原圖保留並且濾鏡轉化後的圖片存放在相對目錄myimg裡面,隨後新建img_video.py將其重新轉換為視訊:

``` import os

圖片轉視訊

os.system("ffmpeg -y -r 15 -i ./myimg/%03d.png -vcodec libx264 ./myvideo/test.mp4") ```

依然是每秒15幀的速率,和原視訊相同。

如果原視訊帶有音軌,可以先將音軌進行分離操作:

```

抽離音訊

import os
os.system("ffmpeg -y -i ./lisa.mp4 -ss 00:00:20 -to 00:00:22 -vn -y -acodec copy ./myvideo/3.aac") ```

進行動漫濾鏡轉換之後,將轉換後的視訊和原視訊的音軌進行合併操作:

```

合併音視訊

os.system("ffmpeg -y -i ./myvideo/test.mp4 -i ./myvideo/3.aac -vcodec copy -acodec copy ./myvideo/output.mp4") ```

原視訊的測試用例:

轉換後效果:

在m1晶片的加持下,基於cpu版本的Pytorch跑起來效率還是不錯的,不過令人遺憾的是適配m1晶片的gpu版本的Pytorch我們還需要等待一段時間,在上個月,Pytorch專案組成員soumith給出過這樣的迴應:

So, here's an update.

We plan to get the M1 GPU supported. @albanD, @ezyang and a few core-devs have been looking into it. I can't confirm/deny the involvement of any other folks right now.

So, what we have so far is that we had a prototype that was just about okay. We took the wrong approach (more graph-matching-ish), and the user-experience wasn't great -- some operations were really fast, some were really slow, there wasn't a smooth experience overall. One had to guess-work which of their workflows would be fast.

So, we're completely re-writing it using a new approach, which I think is a lot closer to your good ole PyTorch, but it is going to take some time. I don't think we're going to hit a public alpha in the next ~4 months.

We will open up development of this backend as soon as we can.

可以看出來,專案組應該是徹底為m1晶片重構Pytorch底層,公開測試版也不會在近期推出,也許明年的下半年會放出來,還是非常值得期待的。

結語:無論是清華大學的CartoonGAN,還是基於CartoonGAN的AnimeGANv2,毫無疑問,它們都是業界的翹楚,是頂峰中的頂峰,就算是放在世界人工智慧的範圍上,擺在PyTorch-GAN這樣的專案旁邊,也是毫不遜色的,在人工智慧領域,AnimeGANv2向世界宣佈,中國人只能製造藥丸補劑的歷史已經一去不復返了。

原文轉載自「劉悅的技術部落格」 https://v3u.cn/a_id_201

「其他文章」