iOSで超解像 - その2：waifu2x-metalをiOSに移植する

「[その1](https://qiita.com/shu223/items/4b8a603215bb50424f85)」では、超解像とは、waifu2xとはなんぞや、という話から、そのMetal実装である[waifu2x-metal](https://github.com/safx/waifu2x-metal)でその威力について試してみました。

簡単におさらいすると、超解像とは、**画像の解像度を高める技術**のことで、100x100ピクセルの画像から200x200ピクセルの画像を生成する、というようなものです。

そしてwaifu2xは**深層畳み込みニューラルネットワークを用いた超解像システム**で、従来の補間処理によるリサイズとはまったく別次元の効果を発揮します。前回記事ではそのMetal実装であるwaifu2x-metalを手元の画像で試し、実際に効果があることを確認しました。

（左）従来法による拡大、（右）waifu2xによる拡大

![](https://qiita-image-store.s3.amazonaws.com/0/3180/473d7dc7-8743-da98-3ac6-958acd00d14f.jpeg)

![](https://camo.qiitausercontent.com/d6c9d46d49b902ae6a4663015c61e40c94481423/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f333138302f34343636613337652d393730382d646366392d653436612d6465366537656535333638662e706e67)

（写真は[itSnap](https://itsnap.jp/theme_%E3%81%A1%E3%81%BE%E3%81%9F%E3%81%AE%E8%A6%96%E7%B7%9A%E3%82%92%E3%81%B2%E3%81%A8%E3%82%8A%E5%8D%A0%E3%82%81%E2%99%A1%E3%83%80%E3%82%B9%E3%83%86%E3%82%A3%E3%83%94%E3%83%B3%E3%82%AF%E3%81%AE%E3%83%AD%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%BC%E3%83%88%E3%81%A7%E5%9C%A7%E5%80%92%E7%9A%84%E3%81%AA%E5%AD%98%E5%9C%A8%E6%84%9F%E3%82%92%E6%94%BE%E3%81%A4-20160328)様より特別に許可をいただき使用させていただきました[^dealforest]）


[^dealforest]: [dealforest](https://twitter.com/dealforest)さんありがとうございます！

waifu2x-metalはmacOSで動くように実装されていますが、**MetalなのでiOSでも動作するはず**です。

これをiOSで**オンデバイスで**利用できれば、アプリのUX改善にとってその効果は絶大です。たとえば、サーバーからは非Retinaサイズで取得しておいて、デバイス側でRetinaサイズに拡大して表示、ということが考えられます。**画像のクオリティは維持しつつ通信量が4分の1**になれば、通信速度というUXにおける大きなボトルネックが改善し、ネットのインフラが十分でない環境でもサクサク画像が表示されるようになる、というような効果が期待されます。

というわけで本記事「その2」では、waifu2x-metalをiOSに移植してみます。


## 修正点

- ベースとなるアプリを作成
  - MTKViewでMTKTextureを表示する
  - 記事末尾の「iOS 11 Programming」にこのへんの基礎的な話を書いてます。
- waifu2x-metalから必要なクラス・リソースファイルを持ってきてプロジェクトに追加する
  - main.swift（waifu2xの実装）
  - functions.metal（コンピュートシェーダ）
  - scaale2.0x_model.json（CNNのパラメータが入ってる）
- main.swiftをiOSで使えるよう修正
  - 本質的な処理は修正不要だが、修正点自体はわりと多い

## 実行結果

まず、おなじみのmacOS High Sierraの画像を500x500に縮小し、実行してみました。

![highsierra.jpg](https://qiita-image-store.s3.amazonaws.com/0/3180/bfcd4489-e227-cb81-2823-3aa96648c4e9.jpeg)

以下その際のログ：

```
32
32
64
64
Message from debugger: Terminated due to memory issue
```

最後のログに"Terminated due to memory issue"とある通り、**GPU側のメモリ不足でクラッシュ**しました（iPhone X利用）。前回記事で試した通り、macOSで実行した際には540×810の画像でいけたのですが、iOSデバイスではこのサイズは（少なくとも現実装では）厳しいようです。

ちなみに[以前に別記事に書いた](https://qiita.com/shu223/items/ebbdc25734d4546a6915)方法でGPU側のメモリ使用量を見てみたところ、こんな感じでした。

```
32
allocated size: 159907840
32
allocated size: 436830208
64
allocated size: 856391680
64
allocated size: 1410334720
Message from debugger: Terminated due to memory issue
```

途中のCNNレイヤでメモリ使用量が約1.4Gに達し、果てています。このあともう3レイヤあるので、全然ダメなようです。

メモリ使用量を減らすといった処理の最適化は今回は置いておいて、もっと小さい画像で試してみます。

![comic_half.png](https://qiita-image-store.s3.amazonaws.com/0/3180/4be5d78c-fd86-987e-52fb-201c9287499f.png)

サイズは220x220です。以下のように、無事最後までiOSデバイス上で処理できました。

```
32
allocated size: 48332800
32
allocated size: 108101632
64
allocated size: 202080256
64
allocated size: 321912832
128
allocated size: 510001152
128
allocated size: 749895680
3
allocated size: 855851008
```

結果的にはmacOSと試したときと同じですが、iOSデバイス上で動いたよということで、処理前後のスクショを載せておきます。

![ios copy.png](https://qiita-image-store.s3.amazonaws.com/0/3180/214db625-1e6e-6ec0-4289-b07d0f1e4269.png)



## 気になるパフォーマンス

「その3」で、気になるパフォーマンスについて書きます。

しかし、もったいぶっても仕方ないので現状について書きますと、**リアルタイム処理には程遠い**です。リアルタイム処理ができないのであれば、前記事や冒頭で書いたようなUX改善のメリットは得られません[^merit]。

[^merit]: とはいえ「画像をiOSアプリ上できれいに拡大できる」という機能は、リアルタイム性がなくても現状でも活用ケースは十分にあると思っています。

しかし、**処理速度の問題、メモリ使用量の問題、どちらも改善の展望**がいくつかあります。waifu2x-metalを実装された方の[元記事](http://safx-dev.blogspot.jp/2015/07/metalwaifu2x.html)で書かれているような点もありますし、もっと別の点でも改善が見込まれると考えています。

そのための要素技術もあるので、いったん他のMetalの記事を書いた後に、「その３」を書く予定です。

Metalアドベントカレンダーのいち記事として書くので、興味のある方はぜひ購読してみてください。

- [Metal Advent Calendar 2017 - Qiita](https://qiita.com/advent-calendar/2017/metal)



## Metalの参考書籍

技術書「[iOS 11 Programming](http://peaks.cc/shu223/iOS11)」の、「第13章 Metal」を執筆しました。

書籍のタイトルにはiOS 11とありますが、Metalについては新機能の紹介だけではなくて、**基礎からじっくり解説**しています。Metalの章だけで**37ページ**もあり、日本語ではこれだけのまとまったMetalの解説はレアかと思います。

- 13.1	はじめに
- 13.2	Metalの概要
- 13.3	Metalの基礎
- 13.4	MetalKit
- 13.5	Metal入門その１ - 画像を描画する
- 13.6	Metal入門その２ - シェーダを利用する
- 13.7	Metal入門その３ - シェーダでテクスチャを描画する
- 13.8	ARKit+Metalその１ - マテリアルをMetalで描画する
- 13.9	ARKit+Metalその２ - MetalによるARKitのカスタムレンダリング
- 13.10	Metal 2
- 13.11	Metalを動作させるためのハードウェア要件

他の章も他著やネットではなかなか得られない濃い情報が詰まっているので、気になった方はぜひ[サンプルPDF](http://peaks.cc/shu223/iOS11)もあるので見てみてください。

- 第1章　iOS 11 概要
- 第2章　ARKit
- 第3章　Core ML
- 第4章　Swift 4の新機能とアップデート
- 第5章　Xcode 9 の新機能
- 第6章　Drag and Drop
- 第7章　FilesとDocument Based Application
- 第8章　レイアウト関連の新機能及び変更点
- 第9章　Core NFC
- 第10章　PDF Kit
- 第11章　SiriKit
- 第12章　HomeKit入門とiOS 11のアップデート
- 第13章　Metal
- 第14章　Audio関連アップデート

PEAKSのサイトにて電子書籍・紙の書籍ともに販売されています。

<div class="peaks_widget" style="overflow:hidden; padding:20px; border:1px solid #dedede;"><div class="peaks_widget__image" style="float:left; margin-right:15px; line-height:0;"><a target="_blank" id="purchase" href="https://peaks.cc/shu223/iOS11"><img alt="iOS 11 Programming" style="border:none; max-width:140px;" src="https://s3-ap-northeast-1.amazonaws.com/peaks-images/project002_cover.jpg" width="500"></a></div><div class="peaks_widget__info"><p style="margin:0 0 3px 0; font-size:110%; font-weight:bold;"><a target="_blank" id="purchase" href="http://peaks.cc/shu223/iOS11">iOS 11 Programming</a></p><ul style="margin:0; padding:0;"><li style="font-size:90%; list-style:none;"><span>著者：</span><span>堤 修一,</span><span>吉田 悠一,</span><span>池田 翔,</span><span>坂田 晃一,</span><span>加藤 尋樹,</span><span>川邉 雄介,</span><span>岸川克己,</span><span>所 友太,</span><span>永野 哲久,</span><span>加藤&#160;寛人,</span></li><li style="font-size:90%; list-style:none;">発行日：2017年11月16日</li><li style="font-size:90%; list-style:none;">対応フォーマット：製本版,PDF</li><li style="font-size:90%; list-style:none;"><a target="_blank" id="purchase" style="text-decoration:underline; color:#1DA1F2;" href="http://peaks.cc/shu223/iOS11">PEAKSで購入する</a></li></ul></div></div>

執筆を担当したARKit、Metalの章の詳細、あるいは全体的なおすすめポイントは以下の記事にも書きました。

- [「iOS 11 Programming」を共著で執筆しました／本書のおすすめポイント - Over&Out その後](http://d.hatena.ne.jp/shu223/20171128/1511827476)