ディープラーニングで新しい画像変換
数ヶ月前ですがディープラーニングの分野で「pix2pix」という技術が話題になりました。これは簡単に言うと画像フィルタを入力画像と出力画像のペア(教師データ)だけから自動で生成してくれる技術です。詳細は、以下の記事や元の論文を参照下さい。
pix2pixの紹介 | 株式会社クロスコンパス・インテリジェンス's Blog
「pix2pix」を使うと、従来の画像処理では難しかった、白黒画像をカラーにしたり、手書きの絵を写真にしたりといった、ぶっ飛んだ画像フィルタを教師データを用意するだけで生成できてしまいます。具体的な応用例に関しては、以下の記事などが参考になります。
できそうなことはだいたいできる画像生成AI、pix2pixの汎用性に驚く - WirelessWire News(ワイヤレスワイヤーニュース)
自分も何か面白い画像変換フィルタ作って見たいなと考えた結果、昔のファミコンのゲームにあるような荒いドット絵を鮮明な画像にできたら面白いのじゃ無いかと思いつきました。画像からドット絵変換に関しては、以前Processingでつくったこともあるので、教師データも簡単に用意できるかなと思ったこともあります(詳しくは以下)。
というわけで、ドット絵から画像変換を試してみることにしました。これ以降は、しばらく興味ない人にとっては宇宙語がつづきますので、手っ取り早く結果が見たいと言う人は、ドット絵の変換結果ということろまで飛ばして下さいね!
pix2pixを使ったドット絵変換
環境構築
「pix2pix」は、ディープラーニングのフレームワークとして、もともとPyTorchを使っているようですが、TensorFlowやChainerでの実装もあるようです。今回はTensorFlow実装の以下リポジトリを使用しましたので。その前提で環境構築していきます。
GitHub - affinelayer/pix2pix-tensorflow: Tensorflow port of Image-to-Image Translation with Conditional Adversarial Nets https://phillipi.github.io/pix2pix/
ただし、上記のプログラムにはもちろんドット絵の変換画像を生成するようなツールがないので、私がforkして今回の目的に合わせてツールを追加した以下のリポジトリを用意しました。
GitHub - karaage0703/pix2pix-tensorflow: Tensorflow port of Image-to-Image Translation with Conditional Adversarial Nets https://phillipi.github.io/pix2pix/
また、今回私はiMacでテストしましたが、Linuxでも基本的に同じ操作でうまくいくと思います(細かいところで違いあったら是非教えて下さい)。Windowsの方はごめんなさい。
Python環境に関しては、基本的には、以下の通りに環境を構築すれば大丈夫です。
バージョンで注意する点としては、Python3(Anaconda3)を使ったことと、TensorFlowのバージョンは1.4.0にしたというくらいでしょうか。TensorFlowはバージョン違うと動かない可能性があるので、具体的には以下のようにバージョン指定でインストールすれば良いと思います。
$ pip install tensorflow==1.4.0
次に、以下のコマンドで私が用意したリポジトリをクローン(コピー)し、pix2pix-tensorflow
ディレクトリに移動します。
$ git clone https://github.com/karaage0703/pix2pix-tensorflow
$ cd pix2pix-tensorflow
これで準備は完了です。
えっ?GitHubとかリポジトリとか何?という人は、まずは以下記事を参照してみてください。
学習データ準備
学習データは自分で手持ちの画像があればそちらを使ってもよいのですが、今回は手軽な方法としてスクリプトを使用して、Caltech101という有名なデータセットをダウンロードして使います。
上記環境準備が終わりpix2pix-tensorflow
ディレクトリに入った状況で以下コマンドでダウンロードと解答ができます。
$ cd tools
$ ./getCaltech101.sh
同じディレクトリに101_ObjectCategories
という大量の画像が入ったディレクトリができたらOKです。ここからは急に泥臭くなるのですが、適当なディレクトリ(images
という名前としたとして以下説明します)を作って、その直下に学習したい画像を101_ObjectCategories
のデータセットから適当に画像をコピーしていって下さい。
単純にコピーすると、同じ名前のファイル名を上書きしてしまうので、コピーしては以下のコマンドで一括リネームを繰り返すと良いと思います。
$ for F in image*; do mv $F ${F/image/panda};done
ちょっと説明わかりにくいかもしれませんが、要はimages
ディレクトリ以下に、以下のような大量の写真が入っていればOKです。ここは気合いです。
拡張子は jpg, png, bmpを想定しています。サイズは適当でもOKです(正方形の256x256pixが理想です)。今回は合計140枚の画像を使いました。
次に、この画像をドット絵に変換した後「pix2pix」で学習できるように、pix2pixのフォーマットに変換する必要があります。pix2pixのフォーマットに関しては、以下が参考になりました。
OpenCVを使って動画からpix2pixの学習モデルを作ってみる | mediba Creator × Engineer Blog
モノクロ画像とかの変換だったら、元々の「pix2pix」に変換ツールが付属しているのですが、ドット絵変換のものは当然ながら無いので自作しましたpixelart.py
というファイル名のものがそうで、ドット絵変換からpix2pixフォーマット変換までを一気にやってくれます。
使い方は、以下のように変換したい画像を入れたディレクトリを引数にしてコマンド実行するだけです。
$ python pixelart.py images
実行すると、pixelart
というディレクトリに以下のようなpix2pix形式の画像が大量に生成されます。
次にこの画像を学習データ(train)とテストデータ(val)に振り分ける必要があります(理由は割愛します)。ここは「pix2pix」に付属しているツールを使います。具体的には以下コマンド実行するだけです。
$ python split.py --dir pixelart
これで、データがtrain
ディレクトリとval
ディレクトリに分かれるので、以下コマンドで学習します。
$ cd .. $ python pix2pix.py --mode train --output_dir pixelart_train --max_epochs 200 --input_dir tools/pixelart/train --which_direction BtoA
今回は、112枚の画像を使って学習しました。GPUを使いませんでしたが、一晩放置しておけば200世代完了しました。200世代完了時のlossは以下くらい。こんなもんなのかな?ちなみに学習データは682MBになりました。でかい…
progress epoch 200 step 112 image/sec 0.7 remaining 0m discrim_loss 0.917141 gen_loss_GAN 1.54649 gen_loss_L1 0.12775 saving model
学習したら、以下コマンドでテストをします。
$ python pix2pix.py --mode test --output_dir pixelart_test --input_dir tools/pixelart/val --checkpoint pixelart_train
テストが完了するとpixelart_test/images
にドット絵から学習モデルを使って生成した画像が出力されています。
ドット絵
変換した画像
正解画像
うん…なんとなくできているようないないような
ドット絵
学習モデルで変換した画像
正解画像
お、これはそれっぽいですね。というわけで、若干不安はありますが、なんとなくできているような気もするのでテストはこれで完了として、いよいよ本番の未知のドット絵から画像を生成させてみましょう。
ドット絵の変換結果
フリー素材のドット絵
フリー素材のドット絵に関しては、素材提供→「Rド」さんでお送りいたします。本当感謝です。懐かしのgeocitiesのサイトに思わず目頭が熱くなりました。掲示板での交流は活発で、まだまだドット絵に根強い人気があることを感じさせます。
今回ダウンロードした画像を、まずはpix2pix-tensorflow/tools/pixelart_test
におきます。次に、この画像をpix2pixフォーマットに変換します。このツールmake_testpixelart.py
も自作しました(もっとスマートな方法あるかも)。こちらも使い方は引数にディレクトリを指定するのみです。具体的には、以下コマンドです。
$ cd tools
$ python make_testpixelart.py pixelart_test
test_pixelart
というディレクトリに以下のようなpix2pixフォーマットの画像が生成されます。
次に、先ほど生成した学習モデルを使って変換を行います。
$ cd .. $ python pix2pix.py --mode test --output_dir pixelart_test --input_dir tools/test_pixelart --checkpoint pixelart_train
pixelart_test/images
以下に画像が生成されます。
スライムっぽいキャラが
より滑らかでヌルヌル感アップ
天使っぽいキャラが
リアルになってちょっとダークサイドな感じに
かわいらしいブタさんモンスターが
グッと凶悪な感じに
若干、DeepDreamのような人工知能生成画像独特の不気味さがありますが、思った以上にそれっぽく変換できているのではないでしょうか?もっと破綻するかと思っていたので、正直びっくりしました。
いつものフリー素材
恒例のフリー素材。もはやこのサイトのLenna)と言っても過言ではない、ロンスタ(id:lonestartx) さんの画像です。いつも提供ありがとうございます!(勝手に使っているだけ)
今回は、ロンスタさんのフリー素材を一旦ドット絵変換して、復元できるかという実験をやってみました。要領は学習のとき実施していることと同じです。
ロンスタさんのフリー素材を例えばlonestar
というディレクトリにぶち込んで、先ほどのドット絵生成ツールを使います。具体的には以下コマンドね。
$ cd tools
$ python pixelart.py lonestar
pixelart
ディレクトリに以下のようなpix2pix形式の画像が生成されます。
あとは以下コマンドで変換しましょう。
$ cd .. $ python pix2pix.py --mode test --output_dir lonestar_test --input_dir tools/pixelart --checkpoint pixelart_train
もともとこんなお茶目なロンスタさんが
ドット絵変換されて…
うわっ…私のロンスタ、グロすぎ…?
ファミ◯ンのドット絵
ここからは、大人の事情で元の絵を貼り付けるのは控えます。元データは海外サイトで公開されているファンアートのものを使いました。生成された画像を見て「あれ?これって?」と色々想像力を働かせていただけると助かります。似ているのはたまたまです。
ぴ、ピ◯キオなのか!?
す、凄くリアルです
世界一有名な兄弟が気持ちリアルに
まあ美味しそうなキノコに、綺麗なお花
モザイク除去
その他、すぐ思いつきそう(?)な応用例としては、男子の永遠の憧れ、大人のビデオのモザイク除去ですね。本当は、それ用の教師データを用意するべきなのですが、ひょっとしてこのドット絵変換でもそれっぽくできるんじゃないのか?と思い、清く正しい性少年として迷いはあったのですが、苦渋の決断でテストいたしました。
結果は…「私はディープラーニングで驚くべき結果を発見したが、ここに記すには余白が狭すぎる」とフェルマーの言葉で濁しておきます。再現方法はここに全て書いてあるので、興味ある方は是非エロのパワーで勉強して試してみて下さい(笑)
ちなみに作ってから、気づいたのですが似たようなこと(人工知能でモザイク復元)をしている人はたくさんいるようです、やはり考えることはみな同じですね。
まとめ
ディープラーニングを使ったドット絵の画像変換をしてみました。無茶だろと思っていたのですが、思っていたよりはそれっぽい結果がでて面白かったです。ドット絵変換は、大した役には立たないのですがうまく考えれば色々な応用が考えられそうですね。
人工知能で、画像処理をしてくれるAdobe Senseiも、画像生成とか変換のところは、恐らく今回使用した技術と同じようなことをしているのじゃないかなと想像しています。
こういった技術も、代表的なものは時間がたったり、お金を出したりすれば誰でも使えるようになっていくと思うのですが、自分で少しプログラムを書けるようになると、今すぐにグッとできる幅が広がって、自分だけのニーズに応えられたり、無料で活用することができるので、興味ある方はこの後関連記事で紹介する記事など参考にすると良いかもしれません。
個人的には、驚異のエロパワーでディープラーニングマスターした人が、物凄い高品質な人工知能モザイク除去機を開発してくれることを待っております。あ、一応言っておきますけど冗談ですからね(笑)
参考リンク
PillowのModeFilterを使って写真を絵画調にする - Qiita
Image-to-Image Translation in Tensorflow - Affine Layer