DCSCNでオリジナルのモデルを作成し、画像を超解像してみた

## はじめに

画像超解像(画質の悪い画像を高画質化すること)を行うにあたり、DCSCNを使用する機会があったため簡単にまとめ。
なお「超解像を行うためのモデルの作成はGPU、アップスケーリングはCPU」と言ったおもしろ構成を想定している。。。
\# この記事を書いた人は画像処理やら深層学習のど素人です
\# したがって、色々と間違いがあると思われますがお手柔らかに

## DCSCN

2017年に発表された超解像技術。
[jiny2001/DCSCN-super-resolution](https://github.com/jiny2001/DCSCN-super-resolution)
劣化画像の高画質化といえばwaifu2xが有名だが、waifu2xはイラストに対して強く、DCSCNは写真に強そう。
waifu2xで人物写真をアプコンするとのっぺりとした感じになり不自然な感じになる。同梱されているphotoモデルを使用しても、うーんと言った感じ

## 検証環境
- GPUサーバ
    - ubuntu 16.04.5
    - python3.5.2
    - tensorflow-gpu==1.10.1
    - numpy==1.14.5
- 非GPUサーバ
    - AmazonLinux(t3.large)
    - python3.6.5   
    - tensorflow==1.1.0
    - numpy==1.17.4

## モデルの作成

画像を任意のディレクトリに放り込む

~~~shell
$ ls ./img-dataset/
001.jpg 002.jpg ...
~~~

以下コマンドで学習開始(バッチサイズやオプションは任意で)

~~~shell
python ./train.py \
--scale=2 \
--dataset=img-dataset \
--batch_num=4 \
--gpu_device_id 1
~~~

学習が終わると、 `models/` に `checkpoint` と `dcscn_*` と言ったファイルが作成される。これらがモデルファイルとなる。  

## 作成したモデルを使用し、超解像
非GPUで超解像する場合は、作成したモデルを、ec2インスタンスへ移動する(手元の環境ではt3.largeで動作確認。それ以下では強制終了した)。
モデルファイルは、 `models/user-model` と言ったサブディレクトリに入れこむと後でコマンドを叩くとき楽。

適当な場所に画像ファイルを配置し、以下のコマンドで超解像が行われる。

~~~shell
# input.jpgを拡大したい場合
# `checkpoint` と `model_name` は適宜変更する
python ./sr.py \
--file=input.jpg \
--checkpoint_dir=models/user-model \
--model_name=L12_F196to48_NIN_A64_PS_R1F32 \
--scale=2
~~~

とまあ、この流れでGPUサーバで作成したモデルを非GPUサーバで動かすことには成功した。とはいえ、当たり前だが、CPUで超解像は超時間がかかるなどで、この手法はお蔵入りとなった。
\# 参考：t3.largeインスタンスで640x551のjpg画像を2倍に超解像するので11分ほど

もちろん、GPUを使用すればこれほど時間はかからないので、このような制約がなければ普通にGPU側で超解像するべき。  

## 実際の超解像比較
おなじみのlenaさん登場。あらかじめオリジナルの画像は縮小(103x103)済みで2倍にスケール。
(waifu2xではscaleのみでnoiseリダクションは行っていない)

|<strong>オリジナル</strong>|<strong>DCSCN</strong>|<strong>waifu2x</strong>|
|---|---|---|
|![lena.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534310/a81778ea-b7bf-5ccf-df5c-b0e6204b8138.jpeg)|![lena_result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534310/1004419c-0cec-7c47-da17-2cae99df1a22.jpeg)|![lena-waifu2x3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534310/28df2047-efca-f244-a7ff-0f9718f7567a.png)|

気持ちwaifu2xのほうが綺麗？(後述するが、PSNR値はwaifu2xのほうが高い)
DCSCNは設定できるパラメータの数が多いから、適切に設定できればさらなる画質向上が期待できるのかも。

## 余談
### 今回DCSCNを用いた背景  
超解像で有名な手法としては、 `waifu2x` や `waifu2x-caffe` があるが、
諸般の事情で独自のモデルを作成し、かつ、waifu2x-caffeのようにCPUを使用したアプコンを行う制約が生じた。
当初は、waifu2xで作成したruaのモデルファイルをcaffeに転用できないか調査したけど、技量不足で断念した。その後、DCSCNの存在を教えてもらい使うことに。

↑の内容をまとめるとこんな感じ

|手法|独自モデル作成|CPUでの動作|
|---|---|---|u
|waifu2x|○|×|
|waifu2x-caffe|×|○|
|DCSCN|○|○|

### モデル作成において  
#### waifu2x  
- 用意した画像が4kなどのサイズが大きめ and ファイル数が多いと、メモリエラーが発生し作成することができなかった(おま環説)
- 対策としては、学習用の画像をリサイズやら画像を分割するなどで対応可能
- 手元に用意したデータセットによって得られたPSNRの値はおおよそ39.42だった

#### DCSCN  
- waifu2xと比較して学習速度が速い
- 学習元データとして用意した4k画像が入力でも滞りなく学習可能
- モデル生成までの総所要時間も少ない
    - DCSCNでは入力の画像をbicubicなどでアップスケールせず画像の特徴を抽出し、cnn-layerから取り出された特徴をアップスケールすると言った処理系で効率化を行っているっぽい？
- 手元に用意したデータセットによって得られたPSNRの値はおおよそ37.51だった

#### 感触
- 手元のデータセットで作成したモデルのPSNR値は、waifu2xに軍配があがった
- しかし、上述したように、人物画を入力とするようなケースでDCSCNは有効かもしれない
- 当たり前だが、インスタンスタイプをそれなりに上げないと、超解像には時間がかかる

## 参考  
- [Fast and Accurate Image Super Resolution by Deep CNN with Skip Connection and Network in Network](https://arxiv.org/ftp/arxiv/papers/1707/1707.05425.pdf)
- [コンピュータビジョンの最新論文調査 Single Image Super-Resolution 前編](https://engineer.dena.jp/2019/09/cv-papers-19-single-image-super-resolution-1.html)