「OpenCV for Unity」AssetのWebGL対応がやって来たヤァ!ヤァ!ヤァ!

**※(2017/04/27)公開しているデモアプリをUnityの新しいバージョンでビルドしたものに変更**
 (webassembly出力を有効にしたサンプルも追加しました)

Unity Advent Calendar 2016、12月6日目の記事です。

#はじめに#

「**[OpenCV for Unity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088)**」がバージョン2.0.9からWebGLプラットフォームに対応しました。

同じタイミングで同作者による顔器官検出Asset「**[Dlib FaceLandmark Detector](https://assetstore.unity.com/packages/tools/integration/dlib-facelandmark-detector-64314)**」もWebGLのサポート追加されたので、組み合わせて使用することでかなり複雑な画像処理アプリがブラウザ上で公開できるようになりました。

インポートからセットアップまでの流れは、[UnityでOpenCVを利用した顔検出・画像処理アプリ事始め](http://qiita.com/utibenkei/items/fb93623a7ccaabb342f2)と[UnityでDlibFaceLandmarkDetectorを利用した顔器官検出アプリ事始め](http://qiita.com/utibenkei/items/2f392d6fa00960f39e45)を参考にしてください。


**この記事では過去にQiitaに投稿したカメラアプリのサンプルをWebGLに対応させていく過程を解説したいと思います。**

#UnityのWebGLプラットフォーム開発について#

Unity5.3あたりからWebGLプラットフォームに正式対応したようです。
実際に試してみると、動作速度はさすがにネイティブ版と比べてみると遅いですが、なんとか許容範囲ぐらいのレベルなのは驚きました。~動作速度の問題については来年初めくらいから実装されていく予定のWebAssembleyに各ブラウザが対応すればもう少し改善すると思います。
スレッド機能のサポートが無い等のプラットフォーム制限がありますが、**基本的には既存のプロジェクトがそのまま出力可能**と考えて良いようです。

詳しいサポート機能や制限については、公式マニュアルの[WebGL での開発を始めるにあたって](https://docs.unity3d.com/ja/current/Manual/webgl-gettingstarted.html)をご覧ください。

##既存プロジェクトをWebGL対応にする方法##

さっそく過去にQiitaに投稿した記事で作成したサンプルアプリ群をWebGL対応させてゆきたいと思います。

> FaceRig無しでも中の人(二次元)になりたい！【Unity × OpenCV × Dlib × Live2D】
 [http://qiita.com/utibenkei/items/15925db826721f6bb00c](http://qiita.com/utibenkei/items/15925db826721f6bb00c)

> ![DlibFaceDetectorWithLive2DSample_cap.gif](https://qiita-image-store.s3.amazonaws.com/0/28558/756362df-df67-f3a4-eae8-78bd9c3c4f04.gif)

* * *

> 「コワすぎ」るカメラアプリ１～歪む顔編～【Unity × OpenCV × Dlib】
> [http://qiita.com/utibenkei/items/9bfe8f273a0cdbbc492b](http://qiita.com/utibenkei/items/9bfe8f273a0cdbbc492b)

> ![KowasugiruWarpCamera_cap1_2.gif](https://qiita-image-store.s3.amazonaws.com/0/28558/49a90e73-4e1e-4bcc-3a24-2f6e109bbb60.gif)

* * *

> 「コワすぎ」るカメラアプリ２～地獄だぞ編～【Unity × OpenCV × Dlib】
> [http://qiita.com/utibenkei/items/a282d277e234ee4c2b29](http://qiita.com/utibenkei/items/a282d277e234ee4c2b29)

> ![KowasugiruJigokuCamera_cap1.gif](https://qiita-image-store.s3.amazonaws.com/0/28558/50106fa9-6883-33d5-f9fb-a42981bfafb8.gif)


上記のサンプルでは「**[OpenCV for Unity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088)**」と「**[Dlib FaceLandmark Detector](https://assetstore.unity.com/packages/tools/integration/dlib-facelandmark-detector-64314)**」を使用しています。
アプリの作成方法、内容は各記事を確認してください。

###ファイルロード部分のコードを書き換える###

Assetに同梱されているサンプルシーンのコードのコミット履歴をみるかぎり、
[https://github.com/EnoxSoftware/OpenCVForUnity/tree/master/Assets/OpenCVForUnity/Examples](https://github.com/EnoxSoftware/OpenCVForUnity/tree/master/Assets/OpenCVForUnity/Examples)


```csharp:WebCamTextureDetectFaceSample.csqiita.cs
cascade = new CascadeClassifier ();
cascade.load (Utils.getFilePath ("lbpcascade_frontalface.xml"));
```

Utils.getFilePath()を使用してStreamingAssetsフォルダからファイルをロードするためのパスを取得する処理部分（WebGLでは同時にメモリ上の仮想ファイルシステムにデータをコピーする処理も行っている）を以下のように、

```csharp:WebCamTextureDetectFaceSample.csqiita.cs
StartCoroutine (Utils.getFilePathAsync ("lbpcascade_frontalface.xml", (result) => {
                cascade = new CascadeClassifier ();
                cascade.load (result);

                webCamTextureToMatHelper.Init ();
            }));
```

新しく追加されたUtils.getFilePathAsync()を使ったコードに置き換えるだけで良いようです。
コルーチンによる非同期処理に変更になることに注意して書き換えます。

###WebGLビルドセッティング###
「Dlib FaceLandmark Detector」の検出用学習データファイル(100MB超)のロード領域が必要になるので、Build Settingsの[WebGL PlayerSetting]-[Publishing Setting]内の[WebGL Memory Size]の値を512に変更します。

**驚くべきことに、たったこれだけの作業でWebGLプラットフォームに向けてビルドが出来るようになりました！**

##ビルド結果 (ブラウザ上で実行可能なサンプル)##

WindowsのChromeとFireFox、MacのSafariとChromeで動作確認しました。
WebCamera映像も問題なく取得できています。WebGLなので、ご覧のブラウザでそのまま試せます。
（読み込み時などにエラーが発生して止まる場合は、ブラウザのキャッシュを削除すると改善することがあるようです）
**※要求するカメラ入力サイズによってシーンをを切り替えて試せるように（640x480 or 320x240）デモアプリを修正しました。**

###FaceRig無しでも中の人(二次元)になりたい！###

[![dlib_with_live2_sample_webg.png](https://qiita-image-store.s3.amazonaws.com/0/28558/952f3563-5e46-79e6-533b-1a6b58b1b83d.png)](https://utibenkei.github.io/DlibFaceLandmarkDetectorWithLive2DSample/webgl_sample/index.html)

- **[WebGL_asm.jp](https://utibenkei.github.io/DlibFaceLandmarkDetectorWithLive2DSample/WebGL_560f3_asm.jp/index.html)** (Unity5.6.0f3)(WebGL対応のブラウザで実行可能)

- **[WebGL_webassembly](https://utibenkei.github.io/DlibFaceLandmarkDetectorWithLive2DSample/WebGL_560f3_webassembly/index.html)** (Unity5.6.0f3)(WebGL対応かつwebassemblyが有効なブラウザならより高速に実行可能)

私のPC環境（MacBookAir2013）では、Webカメラ入力サイズが640x480のシーンだと動きがカクカクでした。(8FPSぐらい？)さすがにLive2DモデルとWebカメラ映像の同時表示は負荷が大きすぎるようです。
カメラ入力サイズ320×240のシーンだと普通に動くのですが、そのぶん顔器官検出の精度は落ちるので、表情を正確に反映させるにはカメラに大きく顔を映す必要がありました。
Live2DのSDKはWebGLプラットフォームにβ対応状態のようですが動作は問題ありませんでした。
※「Dlib FaceLandmark Detector」の検出用学習データファイル(100MB超)のダウンロードが必要なため、通信環境によっては表示までに数分かかるかもしれません。

###コワすぎ」るカメラアプリ ～歪む顔編～＆～地獄だぞ編～###

[![kowasugiru_camera_sample_we.png](https://qiita-image-store.s3.amazonaws.com/0/28558/c5f5ea0d-b24c-d38a-c95d-5fcd1d35302d.png)](https://utibenkei.github.io/KowasugiruCameraSample/webgl_sample/index.html)

- **[WebGL_asm.jp](https://utibenkei.github.io/KowasugiruCameraSample/WebGL_560f3_asm.jp/index.html)** (Unity5.6.0f3)(WebGL対応のブラウザで実行可能) 

- **[WebGL_webassembly](https://utibenkei.github.io/KowasugiruCameraSample/WebGL_560f3_webassembly/index.html)** (Unity5.6.0f3)(WebGL対応かつwebassemblyが有効なブラウザならより高速に実行可能)

私のPC環境（MacBookAir2013）では、Webカメラの入力サイズを640x480のシーンでもほぼ問題ない動作速度でした。
320×240のシーンだとネイティブ実行と遜色ない速度ですが、画像が荒くなり顔器官検出の精度は落ちるので、顔の輪郭が定まらずプルプル震えてしまうのが残念です。
しかしカメラの画像加工の雰囲気は普通に楽しめると思います。
※ダウンロード時間縮小のため「Dlib FaceLandmark Detector」の検出用学習データファイルはモバイル用(16MB)を使用したので若干精度が落ちています。


#まとめ#
WebGLはOSやPCスマホ関係なく対応ブラウザさえあればインストールの手間なしに実行できるので、ユーザーにアプリを試してもらいやすいというメリットがあると思います。
**なにはともあれブラウザ上で画像加工アプリが公開できるのは楽しい！**