1.はじめに
今までのFaceSwapは、個別に学習プロセスが必要なため処理に時間がかかるのが難点でした。今回ご紹介するのは、個別の学習プロセス無しでFaceSwapを実現するSberSwapという技術です。
2.SberSwapとは?
下記の図は、SberSwapのモデル図でAEI-Netと呼ばれており、3つの部分で構成されています。
1つ目がIdentity Encoderで、画像XsからベクトルZidを求めます。2つ目がMulti-level Attributes Encoderdで、U-Netと同様な構造を持ち画像Xtから特徴Zattを取り出します。そして、3つ目がAAD Generatorで、これらの情報から目的とする画像を生成します。
3.コード
コードはGoogle Colabで動かす形にしてGithubに上げてありますので、それに沿って説明して行きます。自分で動かしてみたい方は、この「リンク」をクリックし表示されたノートブックの先頭にある「Colab on Web」ボタンをクリックすると動かせます。
まず、セットアップを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#@markdown #**セットアップ** # Clone github !git clone https://github.com/cedro3/sber-swap.git %cd sber-swap # load arcface !wget -P ./arcface_model https://github.com/sberbank-ai/sber-swap/releases/download/arcface/backbone.pth !wget -P ./arcface_model https://github.com/sberbank-ai/sber-swap/releases/download/arcface/iresnet.py # load landmarks detector !wget -P ./insightface_func/models/antelope https://github.com/sberbank-ai/sber-swap/releases/download/antelope/glintr100.onnx !wget -P ./insightface_func/models/antelope https://github.com/sberbank-ai/sber-swap/releases/download/antelope/scrfd_10g_bnkps.onnx # load model itself !wget -P ./weights https://github.com/sberbank-ai/sber-swap/releases/download/sber-swap-v2.0/G_unet_2blocks.pth # load super res model !wget -P ./weights https://github.com/sberbank-ai/sber-swap/releases/download/super-res/10_net_G.pth # Install required libraries !pip install mxnet-cu112 !pip install onnxruntime-gpu==1.12 !pip install insightface==0.2.1 !pip install kornia==0.5.4 !rm /usr/local/lib/python3.10/dist-packages/insightface/model_zoo/model_zoo.py #change the path to python in case you use a different version !wget -P /usr/local/lib/python3.10/dist-packages/insightface/model_zoo/ https://github.com/AlexanderGroshev/insightface/releases/download/model_zoo/model_zoo.py #change the path to python in case you use a different version # library import import cv2 import torch import time import os from utils.inference.image_processing import crop_face, get_final_image, show_images from utils.inference.video_processing import read_video, get_target, get_final_video, add_audio_from_another_video, face_enhancement from utils.inference.core import model_inference from network.AEI_Net import AEI_Net from coordinate_reg.image_infer import Handler from insightface_func.face_detect_crop_multi import Face_detect_crop from arcface_model.iresnet import iresnet100 from models.pix2pix_model import Pix2PixModel from models.config_sr import TestOptions # --- Initialize models --- app = Face_detect_crop(name='antelope', root='./insightface_func/models') app.prepare(ctx_id= 0, det_thresh=0.6, det_size=(640,640)) # main model for generation G = AEI_Net(backbone='unet', num_blocks=2, c_id=512) G.eval() G.load_state_dict(torch.load('weights/G_unet_2blocks.pth', map_location=torch.device('cpu'))) G = G.cuda() G = G.half() # arcface model to get face embedding netArc = iresnet100(fp16=False) netArc.load_state_dict(torch.load('arcface_model/backbone.pth')) netArc=netArc.cuda() netArc.eval() # model to get face landmarks handler = Handler('./coordinate_reg/model/2d106det', 0, ctx_id=0, det_size=640) # model to make superres of face, set use_sr=True if you want to use super resolution or use_sr=False if you don't use_sr = True if use_sr: os.environ['CUDA_VISIBLE_DEVICES'] = '0' torch.backends.cudnn.benchmark = True opt = TestOptions() #opt.which_epoch ='10_7' model = Pix2PixModel(opt) model.netG.train() |
最初に、画像をFaceswapしてみましょう。sourceとtargetに画像を指定して実行すると、targetの顔がsourceの顔に置き換えられます。ここでは、sourceを松嶋菜々子、targetを石原さとみに設定しています。
自分で用意した画像を使う場合は、examples/imagesにアップロードして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#@title #**画像をFaceswap** #@markdown ・自分の画像は examples/images にアップロードして下さい source = 'nanako.jpg' #@param {type:"string"} target = 'satomi.jpg' #@param {type:"string"} source_path = 'examples/images/'+source target_path = 'examples/images/' + target source_full = cv2.imread(source_path) crop_size = 224 # don't change this batch_size = 40 source = crop_face(source_full, app, crop_size)[0] source = [source[:, :, ::-1]] target_full = cv2.imread(target_path) full_frames = [target_full] target = get_target(full_frames, app, crop_size) final_frames_list, crop_frames_list, full_frames, tfm_array_list = model_inference(full_frames, source, target, netArc, G, app, set_target = False, crop_size=crop_size, BS=batch_size) result = get_final_image(final_frames_list, crop_frames_list, full_frames[0], tfm_array_list, handler) cv2.imwrite('examples/results/result.png', result) |
1 2 3 4 5 |
#@markdown #**画像を表示** #@markdown ・画像は examples/results/results.png に保存されています import matplotlib.pyplot as plt show_images([source[0][:, :, ::-1], target_full, result], ['Source Image', 'Target Image', 'Swapped Image'], figsize=(20, 15)) |
石原さとみの写真の顔だけが、松嶋菜々子に入れ替わったのが分かると思います。
次に、動画をFaceswapしてみましょう。sourceに画像を、videoに動画を設定して実行すると、videoの顔がsourceの顔に置き換えられます。ここでは、sourceをアンジェリーナ・ジョリー、videoを新垣結衣に設定しています。
自分の用意した画像や動画を使いたい場合は、画像はexamples/imagesに、動画はexamples/videoにアップロードして下さい。なお、オンメモリで処理するので、動画はHDで20秒くらいまでにして下さい(長いとクラッシュします)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#@title #**動画をFaceswap** #@markdown ・自分の画像は examples/images にアップロードして下さい\ #@markdown ・自分の動画は examples/videos にアップロードして下さい source = 'angelina.jpg' #@param {type:"string"} video = 'yui.mp4' #@param {type:"string"} source_path = 'examples/images/'+source path_to_video = 'examples/videos/'+video source_full = cv2.imread(source_path) OUT_VIDEO_NAME = "examples/results/result.mp4" crop_size = 224 # don't change this batch_size = 40 source = crop_face(source_full, app, crop_size)[0] source = [source[:, :, ::-1]] full_frames, fps = read_video(path_to_video) target = get_target(full_frames, app, crop_size) START_TIME = time.time() final_frames_list, crop_frames_list, full_frames, tfm_array_list = model_inference(full_frames, source, target, netArc, G, app, set_target = False, crop_size=crop_size, BS=batch_size) if use_sr: final_frames_list = face_enhancement(final_frames_list, model) get_final_video(final_frames_list, crop_frames_list, full_frames, tfm_array_list, OUT_VIDEO_NAME, fps, handler) add_audio_from_another_video(path_to_video, OUT_VIDEO_NAME, "audio") print(f'Full pipeline took {time.time() - START_TIME}') print(f"Video saved with path {OUT_VIDEO_NAME}") |
1 2 3 4 5 6 7 8 9 |
#@markdown #**動画を表示** #@markdown ・動画は examples/results/results.mp4 に保存されています from IPython.display import HTML from base64 import b64encode video_file = open(OUT_VIDEO_NAME, "r+b").read() video_url = f"data:video/mp4;base64,{b64encode(video_file).decode()}" HTML(f"""<video width={800} controls><source src="{video_url}"></video>""") |
新垣結衣のビデオの顔だけがアンジェリーナ・ジョリーに入れ替わりました。
では、また。
(オリジナルgithub)https://github.com/sberbank-ai/sber-swap
(twitter投稿)
公式(SberBank AI)のcolab notebookの推論のセルは、バッチサイズが可変できますが、cedroさんのnotebookでは省略されているように見受けました。
省略した意図を教えていただければ幸いです。
(公式版でバッチサイズを40、100、1と可変して推論しても、生成される動画はすべて一律に同じものでしたので、現状でバッチサイズを指定しても無意味ということでしょうか)
出川さん
バッチサイズは小さくすると速度に影響し、大きくするとメモリの制約の問題があり、デフォルトの40くらいが良いのではと考えてUIからは省き内部の設定のみにしました。UIに出すのは調整する意味が明確にあるものだけにしたいと思っています。
ご回答ありがとうございます。
バッチサイズは精度(生成品質)に影響するものかと思っていましたが、生成速度とメモリ消費に関わる部分なのですね。
私はPRO+を契約しているのでバッチサイズ100でも動きましたが、1でも入力する動画によっては1分程度の尺ですらクラッシュしますね。
とはいえ、DeepFaceLabやFaceSwapはメモリ消費が穏やかな代わりに処理時間が冗長になるので、今後はSimSwapやSberSwapの路線が流行るかもですね。
自分で用意した画像を使う場合は、examples/imagesにアップロードして下さい。
これはどういう意味ですか?自分で用意した画像はexamplesフォルダー内のimagesフォルダーに入れるということでしょうか?
examples。imagesというフォルダーはどこにありますか?
beginnerさん
colabの左のウインドウにファイルを表示させ、examples/imagesの右端にある縦3つの黒丸をクリックし、アップロードを選択します。
あるいは、examples/imagesフォルダにアップロードしたいファイルをドラッグ&ドロップします。
参考:https://blog.kikagaku.co.jp/google-colab-file
画像をアップロードしようとすると、
source = crop_face(source_full, app, crop_size)[0]
の下の部分に赤い波線が表示されうまくいきません。この場合はどうすればよろしいでしょうか?
akmnさん
顔を構成するキーポイント(目、鼻、顎など)の検出に失敗しています。顔全体が写っていて、正面を向いている画像でお試しください。
こんにちわ。
画像がどうやっても認識されず、試しにデフォルトのnanako.jpgの画像を保存→リネームして同じ画像をアップロードしてみたのですが、エラーが出てしまいました。
何か解決策はありますでしょうか。
pepeさん
静止画は、「顔のアップ」、「目線がこちらを向いていない」、「手など顔を遮るものがある」と顔を認識しない場合があります。その場合は、「顔の周囲も写っていて」、「目線がこっちを向いていて」、「顔を遮るものがない」静止画にすると上手くことがあります。まずは試してみて下さい。
どの段階でどんなエラーが出ているのか教えて頂くと、もう少し適切な回答ができかもしれません。
長尺、高画質を実現するためにメモリのクラッシュを避けるためにcolab pro に加入することは解決策として適していますか?
Sayoさん
Colab pro にすると「ハイメモリ設定」でメモリが倍増できるので効果はあります。但し、HDで1分弱だったのが2分強になる程度の効果です。
長尺 高画質を一度で実現する方策はないでしょうか
しのさん
バッチ処理をする形にすれば良いと思います。動画を30秒程度(高画質にする場合はもっと短く)に分割・処理して後で連結すればOKです。
Colab on Webで、以前試したときは使用できたのですが、久しぶりにやってみると、
セットアップで、「OSError: libcudart.so.10.1: cannot open shared object file: No such file or directory」と出て中断し、セットアップできません。これは、自分のPCの問題でしょうか? 解決方法はありますでしょうか?
dcdcpontaさん
情報ありがとうございます。
エラーの原因は、colabの標準cudaバージョンが変更になったからです。
mxnet のインストールバージョンを最新のcudaバージョン(11.2)に変更して修正済です。再度お試し下さい^^。
セットアップで、OSErrorと出て中断し、セットアップできません。
自分のPCの問題でしょうか?
エラーは下記の様に表示されています。
OSError Traceback (most recent call last)
in
34 from utils.inference.core import model_inference
35 from network.AEI_Net import AEI_Net
—> 36 from coordinate_reg.image_infer import Handler
37 from insightface_func.face_detect_crop_multi import Face_detect_crop
38 from arcface_model.iresnet import iresnet100
5 frames
/usr/lib/python3.7/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error)
362
363 if handle is None:
–> 364 self._handle = _dlopen(self._name, mode)
365 else:
366 self._handle = handle
OSError: libcudart.so.10.1: cannot open shared object file: No such file or directory
peaceさん
エラーの原因は、colabの標準cudaバージョンが変更になったからです。
mxnet のインストールバージョンを最新のcudaバージョン(11.2)に変更して修正済です。
再度ブログのリンクから飛んで、お試し下さい^^。
素晴らしい記事をありがとうございます。
1点お伺いさせてください。
Pythonをかじり始めのド初級者なのですが、
このコードはpythonになりますでしょうか?
このコードをお借りしてVSCで貼れば、
ブラウザ上ではなく自身のPC上でPCのパワーを使って処理が出来るのでしょうか。
もしそれであれば、1本2~30秒の制限なく変換ができるのかな、、と思い。
見当違いのご質問でしたらすみません。
さたけさん
自分のPCで動かすことは可能です。但し、そのためには高性能なマシンを用意し、沢山のライブラリを事前にインストールする必要があります。それにしても、この方法は費用対効果が低い。
一番良い方法は、今のオンメモリで一括処理する方法から他の方法に変えることでしょうか。
セットアップの段階でModuleNotFoundError: No module named ‘dill’というエラーが出てしまいました。原因はなんでしょうか?
吉本さん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
素晴らしいコードまとめをありがとうございます。
セットアップを実行してみたのですが、以下のようなエラーが出てしまいました。
ERROR: pip’s dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
tensorflow 2.11.0 requires protobuf=3.9.2, but you have protobuf 3.20.3 which is incompatible.
どうしたら良いでしょうか?
hasidaさん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
以下のエラーが出て、セットアップが進みません。解決方法はありますか?
ModuleNotFoundError: No module named ‘dill’
—————————————————————————
NOTE: If your import is failing due to a missing package, you can
manually install dependencies using either !pip or !apt.
To view examples of installing some common dependencies, click the
“Open Examples” button below.
—————————————————————————
apexさん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
Google Colab Proでsber-swapを、1ヶ月ほど実行して楽しんでおりましたが、一昨日くらいから、11Preparationに以下のようなエラーメッセージが出て、再読み込みしても変わりません。何をどのようにすれば良いのでしょうか。
ModuleNotFoundError Traceback (most recent call last)
in
14 from insightface_func.face_detect_crop_multi import Face_detect_crop
15 from arcface_model.iresnet import iresnet100
—> 16 from models.pix2pix_model import Pix2PixModel
17 from models.config_sr import TestOptions
3 frames
/content/sber-swap/utils/inference/util.py in
12 import os
13 import argparse
—> 14 import dill as pickle
15 #import util.coco
16
ModuleNotFoundError: No module named ‘dill’
—————————————————————————
NOTE: If your import is failing due to a missing package, you can
manually install dependencies using either !pip or !apt.
To view examples of installing some common dependencies, click the
“Open Examples” button below.
—————————————————————————
ぽけぽんさん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
面白いものでしたが次のようなエラーが出て使えなくなりました
解決方法はありますか?
—————————————————————————
NOTE: If your import is failing due to a missing package, you can
manually install dependencies using either !pip or !apt.
To view examples of installing some common dependencies, click the
“Open Examples” button below.
—————————————————————————
エディさん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
面白かったのですが 次のようなエラーが出てできなくなりました
解決方法はありますか?
—————————————————————————
NOTE: If your import is failing due to a missing package, you can
manually install dependencies using either !pip or !apt.
To view examples of installing some common dependencies, click the
“Open Examples” button below.
—————————————————————————
さとさん
情報ありがとうございます。Colabのプリインストールライブラリのdillが無くなったためにエラーが発生していました。修正済みです。再度ブログのリンクからお試しください。
この数日Colabで動かそうとしたら、Preparationの箇所で以下のようなエラーが発生して先に進めなくなりました。ご確認していただけましたら幸いです。
ModuleNotFoundError: No module named ‘onnxruntime’
During handling of the above exception, another exception occurred:
CSFさん
大変遅くなりましたが、エラー修正済みです。ブログのリンクから再度お試しください ^^
このアイテムは Google の利用規約に違反しているため、アクセスできません。
詳細については、Google ドライブ ヘルプセンターをご覧ください。
というアラートが出て、Colabで開けなくなりました。
ご確認いただければ、大変助かります。
よろしくお願い申し上げます。
初めまして(__)
・こちらのコードはまだ正常に動作するのでしょうか?
・動画、画像に制約はあるのでしょうか?例えば、サイズ、形式、性的なものは生成できないなど…
・グーグルコラボの規約違反…とでますが、無視して実行できるのでしょうか?
よろしくお願いします(__)
ハヤトさん
今ブログのリンクから飛んで、proとFreeの両方でやってみました。まだ動きますビデオはHDで20秒くらいを目安に私の場合、「グーグルコラボ契約。。。」は表示されず対応は不明です。
昨日、久しぶりにSberSwapにアクセスしてみたら、使えるように戻っていたので、
また、これまで同様試してみたところ、Upload source image and videoのところで、
以下のようなエラーが出て進みません。(今も試してみましたが同じ状況です。)
imageもvideoもファイルサイズは、以前と同じなのですが、
どうすれば先に進めるのでしょうか。いつも、お願い事ばかりで申し訳ございません。
—————————————————————————
AttributeError Traceback (most recent call last)
in ()
20
21 try:
—> 22 source = crop_face(source_full, app, crop_size)[0]
23 source = [source[:, :, ::-1]]
24 print(“Everything is ok!”)
2 frames
/usr/local/lib/python3.10/dist-packages/insightface/model_zoo/scrfd.py in detect(self, img, threshold, input_size, max_num, metric)
202 input_size = self.input_size if input_size is None else input_size
203
–> 204 im_ratio = float(img.shape[0]) / img.shape[1]
205 model_ratio = float(input_size[1]) / input_size[0]
206 if im_ratio>model_ratio:
AttributeError: ‘NoneType’ object has no attribute ‘shape’
今年の8月下旬に、進化版を紹介されていることに今気づきました。
お騒がせしました。新しいものを試してみます。
すみません、
https://github.com/cedro3/sber-swap/blob/main/FaceSwap.ipynb
で以下のエラーが出ているのですが修正可能でしょうか?よろしくお願い致します。
—————————————————————————
OSError Traceback (most recent call last)
in ()
38 from utils.inference.core import model_inference
39 from network.AEI_Net import AEI_Net
—> 40 from coordinate_reg.image_infer import Handler
41 from insightface_func.face_detect_crop_multi import Face_detect_crop
42 from arcface_model.iresnet import iresnet100
5 frames
/usr/lib/python3.10/ctypes/__init__.py in __init__(self, name, mode, handle, use_errno, use_last_error, winmode)
372
373 if handle is None:
–> 374 self._handle = _dlopen(self._name, mode)
375 else:
376 self._handle = handle
OSError: libcudart.so.11.0: cannot open shared object file: No such file or directory
ジャガーさん
colabのバージョンアップ対応がうまく出来ておらずすみません。ただ、さらに進化したfacefusionがあり、こちらの方が精度も操作性も良いので、こちらをお使いただくとありがたいです。下記、リンクです。
http://cedro3.com/ai/facefusion/
いつも、すいません。
私も、ジャガーさんと同じ状況です。
facefusionも使用していますが、
Startボタンを押しても途中で止まる動画も多く、
SberSwapが使えると、とても助かります。
ご高配のほど何卒よろしくお願い申し上げます。