LoginSignup
1
1

More than 3 years have passed since last update.

Jetson Nanoでスーパーレゾリューション

Last updated at Posted at 2019-06-09

はじめに

この記事はJetson Nanoを使って解像度の低い画像から解像度の高い画像を作る「スーパーレゾリューション」を試したものである。いつも使っているboss.jpgの画像がピンボケしているのが気になっていたので実験。

ソースコードは下記のものを利用。
https://github.com/idealo/image-super-resolution

ディレクトリ構成

「$HOME/Documents/SuperResolution」以下に環境を構築する。最終的には下記のようになる。

├── Documents/
│   ├── SuperResolution/
│   │   ├── image-super-resolution/
│   │   ├── super_res.py
│   │   ├── Pipfile
│   │   └── Pipfile.lock

事前準備

Jetson Nanoの実験環境のまとめ」でセットアップを行なった後、追加で次の作業を行う。

aptによる関連パッケージのインストール

まずはaptで関連パッケージのインストール。

  • git-lfsがないとgit lfsのサブコマンドが使えず重みをダウンロードできない
  • 他のパッケージはnumpyおよびscipyのために必要
ターミナル
apt install git-lfs libfreetype6-dev libblas-dev liblapack-dev libatlas-base-dev gfortran

Pipenvにより環境の構築

$HOME/Documents/SuperResolution以下にPipenvを使って環境を構築する。

ターミナル
yamamo-to@jetson-nano:~$ mkdir Documents/SuperResolution
yamamo-to@jetson-nano:~$ cd Documents/SuperResolution
yamamo-to@jetson-nano:~/Documents/SuperResolution$

Jetson NanoにPipenvでTensorFlowをインストール」と同じように、~/Documents/SuperReoslution以下にPipfileを作成。ただし全く同じではなく指定されているバージョンを用いるよう微修正。

Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[[source]]
name = "nvidia"
url = "https://developer.download.nvidia.com/compute/redist/jp/v42"
verify_ssl = true

[dev-packages]

[packages]
numpy = {version="==1.16.2", index="pypi"}
grpcio = {version="*", index="pypi"}
absl-py = {version="*", index="pypi"}
py-cpuinfo = {version="*", index="pypi"}
psutil = {version="*", index="pypi"}
portpicker = {version="*", index="pypi"}
six = {version="*", index="pypi"}
mock = {version="*", index="pypi"}
requests = {version="*", index="pypi"}
gast = {version="*", index="pypi"}
h5py = {version="*", index="pypi"}
astor = {version="*", index="pypi"}
termcolor = {version="*", index="pypi"}
tensorflow_gpu = {version="==1.13.1+nv19.5", index="nvidia"}
imageio = {version="*", index="pypi"}
Keras = {version="==2.2.4", index="pypi"}
tqdm = {version="*", index="pypi"}

[requires]
python_version = "3.6"

[pipenv]
allow_prereleases = true

Pipfileを置いた後、pipenv installで構築する。

ターミナル
yamamo-to@jetson-nano:~/Documents/SuperResolution$ pipenv install

ISRのインストール

Image Super Resolution(ISR)パッケージをインストールする。公式の手順ではpip install ISRが推奨されているがTensorFlowのバージョンミスマッチにより失敗する。そのためソースコードからインストールする。

ターミナル
yamamo-to@jetson-nano:~/Documents/SuperResolution$ git clone https://github.com/idealo/image-super-resolution.git
yamamo-to@jetson-nano:~/Documents/SuperResolution$ cd image-super-resolution
yamamo-to@jetson-nano:~/Documents/SuperResolution/image-super-resolution$

重みをダウンロードする。

ターミナル
yamamo-to@jetson-nano:~/Documents/SuperResolution/image-super-resolution$ git lfs pull

setup.pyを編集してinstall_requiresから'tensorflow==1.13.1'を削除する。diffを取ると下記の通り。

setup.py
$ git diff
diff --git a/setup.py b/setup.py
index df108a8..e49dd6c 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@ setup(
     description='Image Super Resolution',
     long_description=long_description,
     license='Apache 2.0',
-    install_requires=['imageio', 'Keras==2.2.4', 'numpy==1.16.2', 'tensorflow==1.13.1', 'tqdm'],
+    install_requires=['imageio', 'Keras==2.2.4', 'numpy==1.16.2', 'tqdm'],
     extras_require={
         'tests': ['pytest==4.3.0', 'pytest-cov==2.6.1'],
         'docs': ['mkdocs==1.0.4', 'mkdocs-material==4.0.2'],

編集後、以下のようにインストールする。

ターミナル
yamamo-to@jetson-nano:~/Documents/SuperResolution/image-super-resolution$ pipenv run python3 setup.py install

実験

$HOME/Documents/SuperResolutionで作業を行う。

ターミナル
cd ~/Documents/SuperResolution

ソースコードの準備

以下のようなsuper_res.pyを作成する1

super_res.py
import argparse
import numpy as np
from PIL import Image
from ISR.models import RDN


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('weights_hdf5')
    parser.add_argument('input_image')
    parser.add_argument('output_image')
    args = parser.parse_args()

    img = Image.open(args.input_image)
    lr_img = np.array(img)

    rdn = RDN(arch_params={'C':6, 'D':20, 'G':64, 'G0':64, 'x':2})
    rdn.model.load_weights(args.weights_hdf5)

    sr_img = rdn.predict(lr_img)
    new_img = Image.fromarray(sr_img)

    new_img.save(args.output_image)


if __name__ == '__main__':
    main()

入力画像の準備

boss.jpgに対して実行するとOOM(Out Of Memory)エラーが発生するので、切り出して小さな画像 boss_crop.jpg を使う。

ターミナル
convert boss.jpg -crop 250x240+150+50 boss_crop.jpg

プログラムの実行

先ほど作成したsuper_res.pyを実行する。実行文が長くなっているのは重みファイルが深いところにあるため。

ターミナル
pipenv run python3 super_res.py image-super-resolution/weights/sample_weights/rdn-C6-D20-G64-G064-x2/ArtefactCancelling/rdn-C6-D20-G64-G064-x2_ArtefactCancelling_epoch219.hdf5 boss_crop.jpg boss_hires.jpg

実行ログに「メモリが足らないよ」という警告が散々出るがthis is not a failureを信じることにする。

image_super_resolution.png

結果

成功すると入力画像の倍のサイズの画像が作成される。比較のためにオリジナル画像をImageMagickのconvertでresizeした画像も合わせて掲載する。

クロップ画像(250x240)
boss_crop.jpg

クロップ画像縦横2倍(500x480) by ImageMagick
boss_crop_double.jpg

スーパーレゾリューション(500x480)
boss_hires.jpg

差が分かりにくいので差分(スーパーレゾリューション - クロップ画像縦横2倍)を取る。

boss_diff.jpg

うん、それなりに違うようだ。

そもそも論

スーパーレゾリューションに期待してしていたのは(いつも使っているboss.jpgの)「ピンボケ画像が綺麗になる」ということであり、拡大して綺麗になることではない。ソリューションの選択ミスだったかも知れない。

それならば手動でオートエンコーダしてみよう、ということで画像を一旦半分にして、このスーパレゾリューションに掛けてみる。

boss_crop.jpgboss_hires2.jpg
(左)オリジナル画像 (右)画像を一旦半分にしてスーパーレゾリューション

細かい部分では「障子の模様が変わった」「カタカナが読めない」などあるものの、それなりに改善されたように見える。

まとめ

Jetson Nanoを使ってスーパーレゾリューションを行い、画像を一度半分にしてスーパーレゾリューションを適用することにより、ピンボケ画像の改善が見られた。


  1. このプログラムは一度掴んだGPUのメモリが解放されない問題があるので、一回実行したら再起動が必要である。 

1
1
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
1
1