【HoloLens1】HoloLens で物体のオフライン検出

#HoloLensでオフライン検出
HoloLensで物体のオフライン検出を行います。
作成にあたっては@miyauraさんの記事を参考にさせていただきました。(URLを一番下に記載)

#環境構築
Windows 10 1809 (17763) 以上
HoloLens OS 1809
Visual Studio 2017
Unity 2017.4.17f1

#Custom Visionでのモデル作成(ONNX)
Azureポータルへアクセス
https://portal.azure.com

Cognitive Services リソースの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/42a7ae04-fe7a-12a8-a998-655a51b6793f.png)
名前、サブスクリプション、場所、価格レベル、リソースグループをお好みで指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/56a9084a-0a79-9598-fcea-9a5efbe941bd.png)

作成後、すべてのリソースで「名前」、「名前_Prediction」リソースが作成されている事を確認します。

Azure Custom Visionにアクセス
https://www.customvision.ai

「NEW PROJECT」から新しいプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/04da82c9-455d-5f8c-95a9-32ce2eab0bd2.png)

「Project Types」はObject Detection
「Domains」はGeneral(Compact)
「Export Capabilities」はBasic platformsに設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/2c2c8fef-9759-7002-2dcf-a6906a035d48.png)

プロジェクト作成後は画像をアップロードし、学習を進めていきます。
1タグにつき、少なくとも15枚以上の画像が必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/9a818be9-2d19-7041-81d5-d46798bb6f67.png)

「Export」をクリックし、ONNX1.2を指定した上でzipファイルをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/952fc589-22ab-b278-3014-28ba6902a973.png)

ダウンロード後、zipファイルを解凍し、ファイル内の「model.onnx」を「LearningModel.onnx」に書き換えます。
この.onnxファイルが学習させたデータになっており、プロジェクトにインポートする事で利用可能になります。

#プロジェクトのダウンロード
こちらのURLからプロジェクトをダウンロードします。
https://github.com/namiwavess/ObjDetectionSamplesUsingONNX
ダウンロード後、Unity 2017.4.17f1を起動しプロジェクトを開きます。

#Unityでの作業
プロジェクト設定をHoloLens向けに設定します。

PlatformをUWPに変更します。
Unity C# Projectsにチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/7e59eeda-6fbc-79df-7d44-ce3161793e2c.png)

Scripting Backendは.NETにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/497917c8-91af-f4ba-9deb-43d7fd1ad95a.png)

ビルドを行い成功すれば、Unityでの作業は完了です。

#Visual Studioでの作業
学習させたデータに合わせてタグの変更を行います。**今回の記事では
{"curry","gyoza","meat","pizza","sushi"}になっていますが、学習させた内容に合わせて適宜変更してください。**

```C#:CustomVisionAnalyser.cs
#if UNITY_UWP
        Task.Run(async () =>
        {
            var modelFile = await
                StorageFile.GetFileFromApplicationUriAsync(
                    new Uri("ms-appx:///Assets/LearningModel.onnx"));
            _objectDetection = new ObjectDetection(new List<string>(new[] { "curry", "gyoza","meat","pizza","sushi"}), 20, .3f, .45f);
            await _objectDetection.Init(modelFile);

            IsReady = true;
        });
#endif
```
ターゲットはRelease/X86に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/f1936aa6-35e3-49f0-baba-44932cd24029.png)

学習させた.onnxモデルをAssetフォルダ内にインポートします。
「ビルドアクション」はコンテンツ、「出力ディレクトリにコピー」は常にコピーするを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/1f2a6a33-e284-50b4-fe6e-88092cc63d4a.png)

プロジェクトからNuget管理を開き、System.ValueTuple ライブラリをインポートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/f65eedcf-44f3-b763-37f6-cae1af8b82fb.png)

インポート後、実機にデプロイし、動作を確認します。

#実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299455/fd68d4fb-540e-b7e9-71a6-9196be42a8a2.png)

#まとめ
HoloLensでオフライン検出を行うことができました。推論には時間が掛かりますが、
入力-ONNXモデル-出力 のフローを作ることができれば、多くの分野で活用できそうです。

#参考
HoloLensでAzure Custom Vision Service - ObjectDetectionをWindows MLを使ってオフライン推論してみた。
https://qiita.com/miyaura/items/1b9210b5c5f75d8722a3