[SberSwap] ブラウザで高速にFaceswapを試す [使い方]

2022年2月1日火曜日

Artificial Intelligence

本記事では、SberSwapと呼ばれる機械学習手法を使って、Google Colaboratory上で高速に2つの動画や画像の顔を入れ替える方法を紹介します。

アイキャッチ

概要

DeepFake

DeepFakeとは、ディープラーニングなど高度な合成技術を用いて作られる、本物と見分けがつかないような、にせものの動画を生成する技術を指します。
主に、人間の顔の合成を指すことが多く、大別すると下記の4種類で構成されています。

  1. 顔全体の合成(Entire Face Synthesis)
  2. 属性操作(Attribute Manipulation)
  3. 顔の交換(Identity Swap)
  4. 表情の交換(Expression Swap)

DeepFakeを構成する4つの技術に関する詳細は以下の記事をご覧ください。

faceswap

本記事で紹介するfaceswapは顔の交換(Identity Swap)に属する技術です。

テレビ番組や、YouTubeなどでも著名人の顔を交換した映像をご覧になった方も多いかと思います。

本記事ではGoogle Colaboratoryを使ってGPUを持っていない人でもfaceswapを使用する方法を紹介していきます。

2022年5月時点でGoogle Colabを使用してディープフェイクを作成することが禁止となりました。
詳しくはよくある質問の制限事項をご参照ください。

以降は、参考情報としてご覧下さい。

SberSwap

SberSwapはfaceswapを実現する手法の一つで、AEI-Netをベースに取り入れています。

また高速化にも注力しており、従来手法は交換元・交換先の2つの対象を長時間学習する必要がありましたが、この手法では、画像同士の交換であれば10秒もかからず交換することができます。

さらに、パイプラインには超解像も組み込まれており、faceswapした結果を高解像度化して出力することができます。

以下の記事では従来手法のfaceswapをご紹介していますが、今回の手法の方が圧倒的に早く仕上がります。

faceswapの取り扱いに関する免責事項

faceswapならびに、DeepFakeの技術は悪用によって逮捕者も出ている技術です。
技術そのものに罪はありませんが、厳格な倫理観を持って取り扱うべき技術です。

これからご紹介する技術はあくまでご自身の顔画像処理技術の理解を深めるためにのみご活用ください。本記事を参考にして生じたいかなる損害に関しても当ブログは責任を負いません。

デモ(Colaboratory)

動作環境

ChromeなどのブラウザがインストールされているPCであればスペックは問いません。

ソースコードは以下のGitHubで取得可能です。
GitHub - faceswap Colaboratory demo

または、以下から直接Google Colaboratoryを開くこともできます。
Open In Colab

環境セットアップ

それでは、GitのCloneなど必要な準備を行います。

なお、このデモはPythonで実装しています。
Pythonの実装に不安がある方、Pythonを使った機械学習について詳しく勉強したい方は、以下の書籍やオンライン講座などがおすすめです。

それではセットアップしていきます。 Colaboratoryを開いたら下記を設定しGPUを使用するようにしてください。

「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をGPUに変更

faceswapに必要な作業は、以下の通りソースコードを実行するだけです。

「ランタイム」→「すべてのセルを実行」を選択

あとはセルの出力結果に従って適宜、顔を交換したい動画・画像をアップロードしていきます。

以降は各セルの詳細を記載していきます。

GitHubからCode Clone

始めに、SberSwapのコードをGitから取得します。

%cd /content/
!git clone https://github.com/sberbank-ai/sber-swap.git
%cd sber-swap

学習済みモデルのダウンロード

学習済みモデルをダウンロードします。

顔のパーツの位置を取得するlandmarks detectorや超解像用のモデルなど計4種ダウンロードしています。

# 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

# 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

# SberSwapのダウンロード
!wget -P ./weights https://github.com/sberbank-ai/sber-swap/releases/download/sber-swap-v2.0/G_unet_2blocks.pth

# SuperResolutionのダウンロード
!wget -P ./weights https://github.com/sberbank-ai/sber-swap/releases/download/super-res/10_net_G.pth

ライブラリのインストール・インポート

関連ライブラリをインストールします。

!pip install mxnet-cu101mkl
!pip install onnxruntime-gpu==1.8
!pip install insightface==0.2.1
!pip install kornia==0.5.4

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

from google.colab import files

モデルのビルド・ロード

AEI-Netなどを定義し、学習済みモデルをロードします。

use_sr = Trueの記述がありますが、Trueの場合、出力結果に超解像を行います。
Falseの場合、超解像処理が行われない分出力結果の画質がやや粗くなりますが、処理速度が向上します。

# 初期化
app = Face_detect_crop(name='antelope', root='./insightface_func/models')
app.prepare(ctx_id= 0, det_thresh=0.6, det_size=(640,640))

# modelのbuild
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からface embeddingのロード
netArc = iresnet100(fp16=False)
netArc.load_state_dict(torch.load('arcface_model/backbone.pth'))
netArc=netArc.cuda()
netArc.eval()

# face landmarksのロード
handler = Handler('./coordinate_reg/model/2d106det', 0, ctx_id=0, det_size=640)

# use_sr=True -> 超解像(高解像度化)
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画像のアップロード

FaceSwapしたい画像をアップロードします。
画像を交換するか、動画を交換するか選択することができます。
またアップロードする画像や動画がない場合は、サンプルを選択すると、サンプル画像でFaceSwapを行います。

%cd /content/sber-swap

#@markdown ファイルをアップロードするか、  
#@markdown サンプルを使用するか選択してください。
#@markdown アップデートする場合初めに使用したい顔の画像をアップロードし、
#@markdown 次に顔を当てはめたい画像、または動画をアップロードしてください。
setting_type = 'upload' #@param ["upload", "sample"]

#@markdown videoか、imageのどちらの顔を交換するか選択してください。
target_type = 'image' #@param ["video", "image"]

source_path = 'examples/images/elon_musk.jpg'
target_path = 'examples/images/beckham.jpg'
path_to_video = 'examples/videos/nggyup.mp4'

if setting_type == 'upload':
  # 初めにsourceをアップロード
  upload_src = files.upload()
  upload_src = list(upload_src.keys())
  source_path = upload_src[0]
  
  upload_target = files.upload()
  upload_target = list(upload_target.keys())
  if target_type=='image':
    target_path = upload_target[0]
  else:
    path_to_video = upload_target[0]

FaceSwap

選択したデータを使って、FaceSwapを行います。
出力結果は、examples/results/に出力されます。

#@markdown #**Inference**
batch_size =  40#@param {type:"integer"}

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)

if target_type == 'video':
  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}")
else:
  result = get_final_image(final_frames_list, crop_frames_list, full_frames[0], tfm_array_list, handler)
  cv2.imwrite('examples/results/result.png', result)

FaceSwap結果の表示

それでは、FaceSwapの結果を見ていきます。

余談ですが、moviepyを使うと簡単にColab上にインラインで動画を表示できるためおすすめです。

import matplotlib.pyplot as plt

if target_type == 'image':
  show_images(
      [source[0][:, :, ::-1], target_full, result], 
      ['Source Image', 'Target Image', 'Swapped Image'], 
      figsize=(20, 15))
      
from moviepy.editor import *
clip = VideoFileClip(OUT_VIDEO_NAME)
clip.ipython_display()

本ブログでは、以下の画像を使用しました。
Source画像: https://www.pakutaso.com/20220158028post-38602.html
Target画像: https://www.pakutaso.com/20160337062post-7122.html

input_images

FaceSwapの結果は以下の通りです。

画像のFaceSwap結果

続いてSource画像はそのままに、Targetをこちらの動画に変更しました。
Target動画: https://pixabay.com/ja/videos/%E5%AD%90%E4%BE%9B-%E5%AD%90%E3%81%A9%E3%82%82%E3%81%AE%E7%AC%91%E9%A1%94-%E8%B5%A4%E3%81%A1%E3%82%83%E3%82%93-33631/

input_video

動画のFaceSwap結果は以下の通りです。

output_video

30秒ほどの動画の変換ですが、おおよそ1分程度で完了します。

まとめ

本記事では、Colaboratory上でSberSwapを使用し動画の顔を交換する方法を紹介しました。
従来の手法より高速化が図られているため、素早く様々なFaceSwapを試すことができ便利になっていますね。

また本記事では、機械学習を動かすことにフォーカスしてご紹介しました。
もう少し学術的に体系立てて学びたいという方には以下の書籍などがお勧めです。ぜひご一読下さい。


また動かせるだけから理解して応用できるエンジニアの足掛かりに下記のUdemyなどもお勧めです。

参考文献

1.  論文 - FaceShifter: Towards High Fidelity And Occlusion Aware Face Swapping

2. GitHub - sberbank-ai/sber-swap

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology