1.はじめに
今回ご紹介するのは、年齢による顔の変化をシミュレーションできるDLFS( Disentangled Lifespan Face Synthesis )という技術です。
*この論文は、2021.8に提出されました。
2.LFSとは?
入力画像(Input Image)からエンコーダ(ε)で潜在変数を求め、CNNを使って形状特徴(Shape feature)とテクスチャ特徴(Texture feature)とアイデンティティを抽出します。
そして、アイデンティティを維持しながら、形状特徴とテクスチャ特徴に潜在年齢コード(Latent age code)を加味して特徴を変換し、ジェネレーター(g)でミックスして画像を生成します。
潜在年齢コードは、年齢範囲を6つの離散グループに分割し、対応する年齢コードは隣接した2つの年齢グループの線形補間によって取得します。
それでは、早速コードを動かして見ましょう。
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 |
# githubのコードをコピー !git clone https://github.com/SenHe/DLFS.git %cd DLFS/ # ライブラリーのインストール !pip3 install -r requirements.txt # 補助モデルのダウンロード !python download_models.py # 学習済みモデルのダウンロード import gdown !mkdir checkpoints %cd checkpoints gdown.download('https://drive.google.com/u/0/uc?id=1pB4mufFtzbJSxxv_2iFrBPD3vp_Ef-n3&export=download', 'males_model.zip', quiet=False) !unzip males_model.zip gdown.download('https://drive.google.com/u/0/uc?id=1z0s_j3Khs7-352bMvz8RSnrR53vvdbiI&export=download', 'females_model.zip', quiet=False) !unzip females_model.zip %cd .. # サンプル画像ダウンロード gdown.download('https://drive.google.com/uc?id=1ruwDizjnzd3scR1QvpXGWLXywY8_W0yj', './images.zip', quiet=False) !unzip images.zip |
次に、ライブラリーをインポートし、初期設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# インポート&初期設定 import os from collections import OrderedDict from options.test_options import TestOptions from data.data_loader import CreateDataLoader from models_distan.models import create_model import util.util as util from util.visualizer import Visualizer opt = TestOptions().parse(save=False) opt.display_id = 0 # do not launch visdom opt.nThreads = 1 # test code only supports nThreads = 1 opt.batchSize = 1 # test code only supports batchSize = 1 opt.serial_batches = True # no shuffle opt.no_flip = True # no flip opt.in_the_wild = True # This triggers preprocessing of in the wild images in the dataloader opt.traverse = True # This tells the model to traverse the latent space between anchor classes opt.interp_step = 0.05 # this controls the number of images to interpolate between anchor classes data_loader = CreateDataLoader(opt) dataset = data_loader.load_data() visualizer = Visualizer(opt) |
それでは、年齢による顔アニメーションを行います。性別の設定をopt.name=で行います(女性:females_model, 男性:males_model)。そして、imagesフォルダーに格納されている顔画像のファイル名をimg_file=で指定します。
ここでは、opt.name=’females_model’, img_file=’ 04.jpg’ と設定しています。自分で用意した顔画像を使用する場合は、imagesフォルダーにアップロードして下さい。内部でalign処理(顔を所定の形に切り抜く)を行いますので、顔以外の余分な部分があってもOKです。
内部で、OpenCVを使ってアニメーション(mp4)を作成している関係でコーデックが古くColab上で動かないため、生成した画像は ffmpegでコーデック変換(MP4V→H264)を行い、./output.mp4に保存します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 年齢による顔アニメーション作成 opt.name = 'females_model' # females_model'あるいは'males_model'を選択する model = create_model(opt) model.eval() img_dir ='images' # フォルダー指定 img_file ='04.jpg' # ファイル名 img_path = img_dir+'/'+img_file data = dataset.dataset.get_item_from_path(img_path) visuals = model.inference(data) os.makedirs('results', exist_ok=True) out_path ='results/'+img_file[:-4]+'.mp4' visualizer.make_video(visuals, out_path) # コーデック変換 import os import shutil #shutil.copy('./results/'+img_path[:-4]+'.mp4', './results/out.mp4') shutil.copy(out_path, './results/out.mp4') if os.path.exists('./output.mp4'): os.remove('./output.mp4') ! ffmpeg -i ./results/out.mp4 -vcodec h264 -pix_fmt yuv420p output.mp4 |
1 2 3 4 5 6 7 8 9 10 |
# mp4動画の再生 from IPython.display import HTML from base64 import b64encode mp4 = open('./output.mp4', 'rb').read() data_url = 'data:video/mp4;base64,' + b64encode(mp4).decode() HTML(f""" <video width="50%" height="50%" controls> <source src="{data_url}" type="video/mp4"> </video>""") |
もう1つやってみましょう。今度は、opt.name=’males_model’, img_file=’ 11.jpg’ の設定です。
では、また。
(オリジナルgithub)https://github.com/SenHe/DLFS