15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CartoonGANでgifをアニメ風にする

Posted at

TL;DR

CartoonGANのコードをgifに対応させて試した

はじめに

最近、GAN(Generative Adversarial Network)の実装で、面白いものが増えて来ているような気がしています。
今まで自分でGANを実装したことは無いんですが、CartoonGAN実装が公開されていたので、触って遊んで見ました。
画像をアニメ風に変換するのは、パッケージをいくつかインストールするだけで、すぐに出来ました。
サンプルでgifの結果もあったので、試してみようと思ったのですが、

valid_ext = ['.jpg', '.png']

このようになっていたのでjpgとpngしか変換できませんでした。
またそれ以降の処理を見ても、画像にしか対応しておらず、gifには対応していないようでした。
少々手間だとは思いつつも、せっかくなのでgifでもCartoonGANでアニメ風に変換できるようにしようと思い
ちまちまといじって見ました。
具体的には、gifをフレームごとに分解してCartoonGANで変換し、その画像を一つのgifにまとめただけです。

変更点

gifを一枚ずつ分解する

まずはgifを読み込みます。

input_gif = Image.open(os.path.join(opt.input_dir, filename))

読み込んだgifは

.seek(number)

とすることで、フレーム毎に分割することができるようなので、一枚ずつ分割して、CartoonGANに入力できるようにしておきます。

convert_image

という関数に画像を入力することで、変換された画像が手に入るように書き換えています。

for nframe in range(input_gif.n_frames):
    input_gif.seek(nframe)
    output_image = convert_image(
        model, input_gif.split()[0].convert("RGB"))

CartoonGANで変換された画像を、順番にファイル名をつけながらtmp/以下に保存します。

完成形はこちらです。

input_gif = Image.open(os.path.join(opt.input_dir, filename))
for nframe in range(input_gif.n_frames):
    print("  {} / {}".format(nframe, input_gif.n_frames), end="\r")
    input_gif.seek(nframe)
    output_image = convert_image(
        model, input_gif.split()[0].convert("RGB"))
    save(image=output_image,
         name="tmp/{name}_{nframe:04d}.jpg".format(**{
             "dir": opt.output_dir,
             "name": "{}_{}".format(filename[:-4], opt.style),
             "nframe": nframe
         }))

次で、ファイルを一括で読み込み、gifに整形するのですが、
その時に読み込む順番が変わってしまわないようにするために

{nframe:04d}

としています。
フレームが4桁を超える場合は、ここの数字をいじる必要があります。

複数のjpgをgifにまとめる

次に、先ほど保存したjpgをgifにまとめていきます。
先ほど、ファイル名に数字を割り振り順番が分かるようにしたので
sortしてからjpgファイルを順に読み込み、listにします。

sorted(os.listdir("tmp")):

元のgifファイルの速度と揃えるために、パラメータを与えて保存します。
完成形はこちらです。

def jpg_to_gif(input_image, input_filename):
    images = []
    for filename in sorted(os.listdir("tmp")):
        ext = os.path.splitext(filename)[1]
        if ext not in valid_ext:
            continue
        image = Image.open("tmp/{}".format(filename)).convert("RGB")
        images.append(image)
    images[0].save("{dir}/{name}.gif".format(**{
        "dir": opt.output_dir,
        "name": "{}_{}".format(input_filename[:-4], opt.style)
    }),
        save_all=True,
        append_images=images[1:],
        optimize=False,
        duration=input_image.info["duration"],
        loop=0)

gifファイルの扱いは、知らなければ掴みにくいのですが
分かれば、手間なだけで、特段引っかかることはなさそうです。

Colaboratoryの使い方

ローカルで実行しても良いのですが、pcがすごい熱を発するのでやめておいた方が良いでしょう。
また、cpuでdeep learningを実行するのは、処理時間的に考えてもあまり良い手段では無いと思います。
ということで、いつも通りgoogleにColaboratoryを使わせてもらいます。
gpuで実行したいので、ランタイムがgpuになっていることを確認してから、次のコマンドを実行します。

!git clone https://github.com/t-Asai/CartoonGAN-Test-Pytorch-Torch.git
%cd "CartoonGAN-Test-Pytorch-Torch"
!pip install -r requirement.txt
!sh pretrained_model/download_pth.sh

これで最低限必要な準備は整っているはずです。
オプションをいくつか付けることも可能ですが、一旦何もつけずに実行します。
この実行の仕方だと、jupyter notebookである必要性がカケラもないのは目を瞑る

!python test.py

これで、test_output以下に、結果が保存されていることが分かるかと思います。
ここまでで動作確認は終わりです。

次は、自分のgifファイルを良しなに変更するために
colaboratory上にファイルをアップロードしたり、変換後のファイルをダウンロードする方法について説明します。
やり方を見つけるまでは苦労するかもしれませんが、
見つけてしまえば単純です。

google.colab

を使ってアップロードとダウンロードが可能です。
「zipにしてからダウンロードしたい」などの要望がある場合は、shellをcolaboratory上で実行すれば可能です。

from google.colab import files
import os
files = files.upload()
for filename in sorted(os.listdir("test_output")):
  files.download("test_output/{}".format(filename))

google driveとcolaboratoryを同期させる方法もありますが、
個人的に、あまり好きな方法ではないので使いません。

結果

gifファイルでも、問題なくアニメ風に変換することができるようになりました。

demo_ori.gifdemo.gif

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?