[CCPL] AIで任意の画像のスタイルを動画に転送する

2022年9月21日水曜日

Artificial Intelligence

本記事では、CCPLと呼ばれる機械学習手法を用いて、画像のスタイルを任意の動画に転送する方法をご紹介します。

アイキャッチ

CCPL

概要

Contrastive Coherence Preserving Loss(CCPL)は、芸術的あるいは写実的な画像のスタイルをビデオに転送するスタイル転送手法です。

従来手法では、ビデオへの転送時に時間的な一貫性を維持するために画像全体に強い制約を課していましたが、それでも一貫性を維持することが困難でした。本手法ではローカルパッチにCCPLを適用することで、スタイルを低下させることなくコンテンツの一貫性を維持することを可能にしています。

また近隣調整メカニズム(neighbor-regulating mechanism)により局所的な歪みを減少させ、視覚的な品質を大幅に向上させています。加えてSimple Covariance Transformation(SCT)によりコンテンツとスタイルの特徴を効果的に調整し、自然な融合を実現しています。

アーキテクチャ

詳細はこちらの論文をご参照ください。

本記事では上記手法を用いて、任意の動画に画像のスタイルを転送していきます。

デモ(Colaboratory)

それでは、実際に動かしながら動画に画像のスタイルを転送していきます。
ソースコードは本記事にも記載していますが、下記のGitHubでも取得可能です。
GitHub - Colaboratory demo

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

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

環境セットアップ

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

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

初めにGithubからソースコードを取得します。

%cd /content

!git clone https://github.com/JarrentWu1031/CCPL.git

次にライブラリをインストールします。

%cd /content/CCPL

!pip install --upgrade gdown
!pip install -r requirements.txt

!pip install moviepy==0.2.3.5 imageio==2.4.1
!pip install yt-dlp

最後にライブラリをインポートします。

import os

from yt_dlp import YoutubeDL
from moviepy.video.fx.resize import resize
from moviepy.editor import VideoFileClip

from PIL import Image
import IPython

以上で環境セットアップは完了です。

学習済みモデルのセットアップ

続いて、論文発表元が公開している学習済みモデルをダウンロードしていきます。

%cd /content/CCPL
!mkdir -p pretrained/art pretrained/photo models

# https://drive.google.com/drive/folders/1XxhpzFqCVvboIyXKLfb2ocJZabPYu3pi
art_decoder_ckpt = 'pretrained/art/decoder_iter_160000.pth.tar'
if not os.path.exists(art_decoder_ckpt):
  !gdown --id 1QSTHPqhsyReU4BKtCQIWJC5tL1nXBUOt \
          -O {art_decoder_ckpt}

art_sct_ckpt = 'pretrained/art/sct_iter_160000.pth.tar'
if not os.path.exists(art_sct_ckpt):
  !gdown --id 1ccA2Slqr8wptQtFjs7kHCkemKxT642Ud \
          -O {art_sct_ckpt}

photo_decoder_ckpt = 'pretrained/photo/decoder_iter_160000.pth.tar'
if not os.path.exists(photo_decoder_ckpt):
  !gdown --id 1GothVHT9sWCwrggQWEdTchVu3FlPx9Fx \
          -O {photo_decoder_ckpt}

photo_sct_ckpt = 'pretrained/photo/sct_iter_160000.pth.tar'
if not os.path.exists(photo_sct_ckpt):
  !gdown --id 1LHAbK4gUlmY2QWHKzf6gfUOSiGKxvETv \
          -O {photo_sct_ckpt}


vgg_ckpt = 'models/vgg_normalised.pth'
if not os.path.exists(vgg_ckpt):
  !gdown --id 1EpkBA2K2eYILDSyPTt0fztz59UjAIpZU \
          -O {vgg_ckpt}

テスト画像・テスト動画の取得

続いて、転送先のテスト画像とテスト動画をダウンロードしていきます。

%cd /content/CCPL

!mkdir test_img

!wget -c https://www.pakutaso.com/shared/img/thumb/TSJ86_date20150208082618_TP_V4.jpg \
      -O test_img/test_01.jpg


video_url = 'https://www.youtube.com/watch?v=G6FOe8mu21g' #@param {type:"string"}

#@markdown 動画の切り抜き範囲(秒)を指定してください。\
#@markdown 30秒以上の場合OOM発生の可能性が高いため注意
start_sec =  19#@param {type:"integer"}
end_sec =  24#@param {type:"integer"}

(start_pt, end_pt) = (start_sec, end_sec)

%cd /content/CCPL

!mkdir -p test_video/frames

download_resolution = 720
full_video_path = '/content/CCPL/test_video/full_video.mp4'
input_clip_path = '/content/CCPL/test_video/clip_video.mp4'

# 動画ダウンロード
ydl_opts = {'format': f'best[height<={download_resolution}]', 'overwrites': True, 'outtmpl': full_video_path}
with YoutubeDL(ydl_opts) as ydl:
    ydl.download([video_url])

# 指定区間切り抜き
with VideoFileClip(full_video_path) as video:
    subclip = video.subclip(start_pt, end_pt)
    subclip.write_videofile(input_clip_path)

ダウンロードした画像と動画は後ほど転送結果と共に記載します。

画像へのスタイル転送

ここではまず、先ほどダウンロードした画像にスタイル転送していきます。
画像への転送用スクリプトが用意されているのでそれに引数を指定して実行します。

%cd /content/CCPL

# testing_mode art or pho
!python ./test.py \
  --vgg models/vgg_normalised.pth \
  --SCT pretrained/photo/sct_iter_160000.pth.tar \
  --decoder pretrained/photo/decoder_iter_160000.pth.tar \
  --content test_img/test_01.jpg \
  --style input/style/sketch.png \
  --testing_mode pho \
  --output outputs/imgs

出力結果は以下の通りです。
左上の画像が転送前画像、中央下の画像がスタイルを転送する画像、右上の画像が転送後画像です。
写真がスケッチ風の画像にスタイル転送されています。

ImgResult

動画へのスタイル転送

続いて、動画へスタイル転送を行います。
処理概要としては、フレーム画像に連続的にスタイル転送を行います。

# フレーム画像生成
%cd /content/CCPL

!ffmpeg -i {input_clip_path} test_video/frames/%06d.png

# 一部ソースコード修正
!sed -i /content/CCPL/test_video_frame.py -e "s/transforms.Scale/transforms.Resize/g"

!python ./test_video_frame.py \
  --vgg models/vgg_normalised.pth \
  --SCT pretrained/art/sct_iter_160000.pth.tar \
  --decoder pretrained/art/decoder_iter_160000.pth.tar \
  --content_dir test_video/frames \
  --style_path input/style/4.jpg \
  --testing_mode art \
  --output outputs/videos/art \
  --preserve_color

出力結果は以下の通りです。

スタイル画像

video1

上記画像のスタイルを転送した動画は以下の通りです。

stayle tranfer result

動画に対して一貫性を維持してスタイルが転送されています。

まとめ

本記事では、CCPLを用いて任意の画像・動画にスタイル転送を行う方法をご紹介しました。
使い方次第では、ユニークな動画が作成できそうです。

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


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

参考文献

1.  論文 - CCPL: Contrastive Coherence Preserving Loss for Versatile Style Transfer

2. GitHub - JarrentWu1031/CCPL

AIで副業ならココから!

まずは無料会員登録

プロフィール

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

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


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology