waifu2xをローカルのWindows環境で試す

 少し前に話題になった画像アップスケーラのwaifu2xですが、当初はWEBアプリとして実装され公開されていました。
 技術評論社の以下の記事でUbuntuでのビルド方法などが紹介されていますが、Windows PCならバイナリリリースを使えば簡単に実行できそうなので試してみました。
第586回 waifu2xで画像をきれいに拡大する:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
 

準備

 使用するのはオリジナルのwaifu2xではなく、上記の技評のページで紹介されているwaifu2x-converter-cppというOpenCVを利用してC++で実装されたfork版です。
GitHub - DeadSix27/waifu2x-converter-cpp: Improved fork of Waifu2X C++ using OpenCL and OpenCV
 Windows環境で使用する場合は、Releases · DeadSix27/waifu2x-converter-cpp · GitHubからビルド済みバイナリをダウンロードすることができます。
 インストーラーは無いので、ZIPを展開後任意のディレクトリに配置するだけです。
 

実行

 事前にwaifu2x-converter-cpp.exeを格納したディレクトリにPATHを通していても、同梱のリソースが見つからない系のエラーが発生しました。
 waifu2x-converter-cpp.exeを格納したディレクトリをカレントディレクトリにしてから実行すれば問題なく実行できます。
 

パラメータ

 まず、以下のようにhelpオプションを指定して実行してみると、必要なパラメータが判ります。

> waifu2x-converter-cpp.exe --help

USAGE: 

   waifu2x-converter-cpp.exe  [--list-supported-formats]
                              [--list-opencv-formats] [-l] [-f <png,jpg
                              ,webp,...>] [-c <0-9>] [-q <0-101>]
                              [--block-size <integer>] [--disable-gpu]
                              [--force-OpenCL] [-p <integer>] [-j
                              <integer>] [--model-dir <string>]
                              [--scale-ratio <double>] [--noise-level <0|1
                              |2|3>] [-m <noise|scale|noise-scale>] [-v
                              <integer>] [-s] [-r <bool>] [-o <string>] -i
                              <string> [--] [--version] [-h]


Where: 

   --list-supported-formats
     dump currently supported format list

   --list-opencv-formats
      (deprecated. Use --list-supported-formats) dump opencv supported
     format list

   -l,  --list-processor
     dump processor list

   -f <png,jpg,webp,...>,  --output-format <png,jpg,webp,...>
     The format used when running in recursive/folder mode

     See --list-supported-formats for a list of supported
     formats/extensions.

   -c <0-9>,  --png-compression <0-9>
     Set PNG compression level (0-9), 9 = Max compression (slowest &
     smallest)

   -q <0-101>,  --image-quality <0-101>
     JPEG & WebP Compression quality (0-101, 0 being smallest size and
     lowest quality), use 101 for lossless WebP

   --block-size <integer>
     block size

   --disable-gpu
     disable GPU

   --force-OpenCL
     force to use OpenCL on Intel Platform

   -p <integer>,  --processor <integer>
     set target processor

   -j <integer>,  --jobs <integer>
     number of threads launching at the same time

   --model-dir <string>
     path to custom model directory (don't append last / )

   --scale-ratio <double>
     custom scale ratio

   --noise-level <0|1|2|3>
     noise reduction level

   -m <noise|scale|noise-scale>,  --mode <noise|scale|noise-scale>
     image processing mode

   -v <integer>,  --log-level <integer>
     Set log level (0-4)

   -s,  --silent
     Enable silent mode. (same as --log-level 1)

   -r <bool>,  --recursive-directory <bool>
     Search recursively through directories to find more images to
     process.

     If this is set to 0 it will only check in the directory specified if
     the input is a directory instead of an image.

     You mustn't supply this argument with something other than 0 or 1.

   -o <string>,  --output <string>
     path to output image file or directory  (you should use the full path)

   -i <string>,  --input <string>
     (required)  path to input image file or directory (you should use the
     full path)

   --,  --ignore_rest
     Ignores the rest of the labeled arguments following this flag.

   --version
     Displays version information and exits.

   -h,  --help
     Displays usage information and exits.


   waifu2x OpenCV Fork - https://github.com/DeadSix27/waifu2x-converter-cpp

 というわけで、waifu2xにはスケーリングだけではなく、ノイズリダクション機能もあるようです。
 例えば処理対象画像ファイルを2.5倍にアップスケールするには、以下のようなオプション指定でコマンド実行することになります。

waifu2x-converter-cpp -m scale --scale-ratio 2.5 -i \FULLPATH\TO\INFILE -o \FULLPATH\TO\OUTFILE

 なお、入出力ファイルのパス指定は相対パスでは機能しないようですので、フルパス指定が必要な点に注意が必要です。
 

処理装置指定

 CPU以外にGPUを搭載したマシンであれば、何を使って処理を行うか指定することが可能です。
 予め利用可能なプロセッサを確認するには、以下のコマンドを実行します(--list-processorは-lでも可)。

> waifu2x --list-processor
   0: Ellesmere                                    (OpenCL    ): num_core=32
   1:       Intel(R) Xeon(R) CPU E3-1225 V2 @ 3.20GHz(AVX       ): num_core=4

 Intel Xeon E3-1225 V2 (Ivy Bridge)にAMD Radeon RX470(Ellesmere)を積んだマシンではこのように表示されました。

 各プロセッサ名の前に表示されている番号を--processorオプションに指定すると、当該プロセッサで処理させることが可能です。(--processorは-pでも可)

waifu2x-converter-cpp --processor 1 -m scale --scale-ratio 2.5 -i \FULLPATH\TO\INFILE -o \FULLPATH\TO\OUTFILE

 あるいは、--disable-gpuを使えばCPUで処理されますし、--force-OpenCLを指定すればインテルプラットフォームならOpenCLで処理されます。

 なお、これらのオプション未指定時には一番高速なものが使用されるようですので、特に事情が無ければ指定する必要は無いでしょう。
 

処理速度

 約12MPのスマートフォンで撮影した画像を2倍にアップスケール(3008x4016 ⇒ 6016x8032)した場合、以下のような結果となりました。

Parameter Processor ProcessingTime
-m scale OpenCL: Ellesmere Took: 38.603secs total, filter: 24.900secs; 0 files skipped, 0 files errored. [GFLOPS: 770.16, GFLOPS-Filter: 1194.00]
-m scale --disable-gpu CPU: Intel(R) Xeon(R) CPU E3-1225 V2 @ 3.20GHz Took: 319.335secs total, filter: 306.777secs; 0 files skipped, 0 files errored. [GFLOPS: 93.10, GFLOPS-Filter: 96.91]

 トータル時間で比較して、GPU(RX470)の方がCPU(Xeon E3-1225V2)より約8.27倍高速に処理を終えています。

 また、同一画像に対してノイズリダクションを行った場合、以下のような結果となりました。

Parameter Processor ProcessingTime
-m noise --noise level 3 OpenCL: Ellesmere Took: 10.110secs total, filter: 6.368secs; 0 files skipped, 0 files errored. [GFLOPS: 738.12, GFLOPS-Filter: 1171.87]
-m noise --noise level 3 --disable-gpu CPU: Intel(R) Xeon(R) CPU E3-1225 V2 @ 3.20GHz Took: 80.416secs total, filter: 76.942secs; 0 files skipped, 0 files errored. [GFLOPS: 92.79, GFLOPS-Filter: 96.98]

 トータル時間で比較して、GPU(RX470)の方がCPU(Xeon E3-1225V2)より約7.95倍高速に処理を終えています。

 これらのことから、waifu2xではざっくりと8倍程度GPU(RX470)の方がCPU(Xeon E3-1225V2)より高速に処理できるようです*1
 

処理結果

 冒頭にリンクを張った技評の記事中の図5を拡大した図6について「とてもきれいに拡大されていることがわかります。」と記述されているのですが、私の個人的な感覚では「とてもきれいに」には該当しません。言葉で表現するなら「特別汚くはならずに拡大されている」とでも言った感じでしょうか。
 そもそも、waifu2xはいわゆるアニメ絵のアップスケールに特化されているはずで、技評のサンプルのように普通の写真を拡大することに適しているとは謳われていないはずです。
 というわけで、本当に写真が「とてもきれいに」アップスケールできるのかを含めて確認してみることにします。なお、いわゆるアニメ絵については自分で描けないので今回の検証対象外としますが、検索すれば多くのサンプルが見つかるように、優れたアップスケール結果を得られるようです。
 

サンプル1(写真/高感度)

 いきなり最も厳しいであろうデータパターンから試します。
 スマートフォンで撮影したスカイツリーの夜景画像で、感度ISO800で撮影した写真です*2
スマートフォンで撮影した夜景画像(ISO800)

 これをピクセル等倍で切り出すと以下で、センサーサイズが大きくないこともあって高感度ノイズが目立ちます。
スマートフォンで撮影した夜景画像(ピクセル等倍)

 この画像をwaifu2xで2倍に拡大し、ノイズレベル指定値を変えた場合の結果を示します。

waifu2x(ノイズリダクション無し)
f:id:kachine:20191113004110p:plain
waifu2x(ノイズレベル1)
f:id:kachine:20191113004157p:plain
waifu2x(ノイズレベル2)
f:id:kachine:20191113004222p:plain
waifu2x(ノイズレベル3)
f:id:kachine:20191113004247p:plain

 主観ですが、とても「とてもきれいに」とは評価できません。スカイツリー展望台部の上下方向に無数にある直線がノイズと混ざって、現実には存在しない模様が現れています。また、ノイズレベルを上げると(昔ながらの良くない意味での)ソフトウェアノイズリダクションが効き、べた塗に近い領域が増え、元画像のノイズの多さと相まって油絵調に近くなってしまっています。

 比較対象として、既存の各種アルゴリズムで2倍に拡大した場合も示します*3

 え?どれも同じじゃないかって?確かに元画像のノイズ量の多さも手伝って、どのアルゴリズムが最も優れているかを判断するのは難しい*4です。
 減色処理等によって比較の正確性は下がりますが、アニメーションGIF化したものを見ると違いが分かりやすくなると思います。
waifu2x比較(サンプル画像1)

 既存のいずれのアルゴリズムでも、waifu2xで現れた展望台部の現実には存在しない模様のような、実在しない輪郭が生成されることはありません。waifu2xはノイズも含めて「これ、連続した線分なんじゃね?」とニューラルネットワークが誤判断してしまっているため、このような結果となっているのではないかと想像されます。
 蛇足ながら、これは重要なことで、最近のスマートフォンや監視カメラ周りの技術にはAI技術を取り入れたと謳う製品やサービスが多くあります。が、このwaifu2xのテストで現れた現実には存在しない模様のように、現実とは全く異なる出力が得られる可能性があるわけです。すなわちAIで加工済のデータしか記録されないシステム(新しめのスマートフォンのカメラなど)では、現実にはどうだったのか担保する手段がなくなってしまいます。例えば裁判の証拠のような用途では、(AIによる加工の有無で変わることが無いほど)犯行場面が大きく鮮明に映っているのならともかく、監視カメラ映像中のごく小さな領域の数ピクセルで、犯行の証拠としての人や手や凶器やモノなどが写っているような場合、AIによる加工によって事実とは異なる状況が記録される可能性も否定できないかもしれません。もっとも、AI技術の導入有無にかかわらず、そんな数ピクセルでしか判らない画像や映像が犯行の証拠として採用され得るのかは疑問ですが。
 

サンプル2(写真)

 ミラーレスカメラで撮影した月をクロップした画像で、基本感度(ISO200)から増感していないこともあり、視認できるノイズは皆無です。
ミラーレスで撮影した画像をクロップ(基本感度)

 この画像もwaifu2x及び既存の各種アルゴリズムで2倍に拡大した場合の結果の左上を、ピクセル等倍で切り抜いた画像を示します。

waifu2x(ノイズリダクション無し)
f:id:kachine:20191113012316p:plain
waifu2x(ノイズレベル1)
f:id:kachine:20191113012350p:plain
waifu2x(ノイズレベル2)
f:id:kachine:20191113012407p:plain
waifu2x(ノイズレベル3)
f:id:kachine:20191113012421p:plain

 このサンプルでも全部同じに見えるという方のために、アニメーションGIF化してみると以下のようになります。
waifu2x比較(サンプル画像2)

 主観ですが、このサンプルの場合には変な輪郭が現れずシャープ感もあるKaiserやParzenあたりがマイナーながら最も適しているように見えます。
 waifu2xはやはり微細な点を繋げて連続した線分にしたがる傾向があるように思え、ノイズレベル指定時はべた塗感が強くなるように思えます。ノイズレベル3指定時に至っては、これが人が描いたアニメ絵ならとても凄いと称賛するレベルですが、実写画像としてはとてもあり得ません。
 

画像サンプル3(アスキーアート)

 waifu2xが適しているアニメ絵に近い性質の画像を考えてみると、輪郭線がはっきりしていて複雑な諧調が無い画像だろうか。という考えで、Pi-holeロゴのアスキーアートスクリーンショットした画像で試してみます。
アスキーアート(スクリーンショット)

 面倒なので、以下の結果は簡略化して掲載します(waifu2xのデフォルトは、倍率2倍・ノイズレベル1になるようです。また、ImageMagickの方は拡大アルゴリズムがMitchellが使われるようです)。

waifu2x(デフォルト)
f:id:kachine:20191113020322p:plain
ImageMagick(デフォルト)
f:id:kachine:20191113015938p:plain

 waifu2xの方はくっきりはっきりしている一方、ImageMagickの方は輪郭がぼやけた感じになっており、このパターンでは明らかにwaifu2xの方が優れているように思えます。
 

画像サンプル4(画面スクリーンショット)

 画像サンプル3と同様に、waifu2xに適しているであろう性質の画像として、PCの画面スクリーンショット(ダイアログ)で試してみます。
スクリーンショット(ダイアログ)

 結果をピクセル等倍で切り抜いた画像は以下。

waifu2x(デフォルト)
f:id:kachine:20191113020834p:plain
ImageMagick(デフォルト)
f:id:kachine:20191113020846p:plain

 画像サンプル3の場合と同様に、waifu2xの方がくっきりはっきりしている一方、ImageMagickの方は輪郭がぼやけた感じとなっています。ただ、waifu2xの方をよく見るとノイズリダクションが効きすぎいるのか、漢字の横棒の太さが一定でなかったり、漢字の線の近傍が背景色の青であるべきところが、黒っぽくなっている箇所がごく僅かに存在します。双方デメリットはあるものの、waifu2xの方がぱっと見優れているように思えます(ここで挙げたwaifu2xのデメリットは凝視するような画像でなければ特に問題無いでしょう)。
 

まとめ

実行環境について

 Windows環境でも手軽にwaifu2xを実行できることが判りました。
 ただし、ディスクリートGPU無しでスマートフォンを含め一般的なデジタルカメラの画像と同等の解像度の画像をアップスケールするには長時間を要します。私はPCでゲームはしないのでGPUにこだわりが無かった人間なのですが、同じような考えの方でも機械学習やその成果を応用したソフトウェアを快適に利用するにはGPUは必須と言えるでしょう。
 蛇足ながら、今回使っているAMD Radeon RX470はマイニング用途でディスプレイ出力端子のないモデルが格安で放出されていたものを利用していますが、本来は機械学習に適した環境を構築しようと思って購入しました。が、NvidiaのCUDAが使えないと利用できないソフトウェアが多く、機械学習用にはあまり向いていないと言えます。といった個人的反省を踏まえると、現時点では比較的安価で消費電力少な目で、絶大な効果ではなくてもしっかりと恩恵が感じられるクラスの製品だとNvidia GeForce GT1030とかGT1050辺りが入門用には良いのではないかと思います*5

MSI GeForce GT 1030 2G LP OC グラフィックスボード VD6348

MSI GeForce GT 1030 2G LP OC グラフィックスボード VD6348

 

waifu2xの処理結果について

 また、画像サンプル1,2の結果からも解るとおり、waifu2xは写真のアップスケールには適していません。
 一方で、waifu2xが優れてると言われる本来の用途であるアニメ絵ではなくても、それと似たような性質、すなわち線がハッキリしており複雑な諧調性が無いような画像については優れたアップスケール結果を得ることができるとも言えそうです。
 



以上。

*1:当然ですが使用するGPUやCPUの違いによりこの性能比は異なります。

*2:掲載しているのは縮小した画像

*3:いずれもImageMagickで生成。

*4:ImageMagickのアップスケール時のデフォルトのフィルタはMitchellだそうで、確かにバランス良さそうな出力が得られている感じがします。

*5:PCの電源容量やPCIスロットの形状等によって利用可否がありますので購入の際はご注意ください。