Hololens SpectatorViewをやってみた

# はじめに
HololensのSpectatorViewを試してみたところ、いろいろ引っかかったためメモ

# SpectatorViewとは？
Microsoftが提供している。詳しくは以下。
https://docs.microsoft.com/en-us/windows/mixed-reality/spectator-view
https://github.com/Microsoft/MixedRealityCompanionKit/tree/master/SpectatorView

ざっくりいうと、Hololensの「カメラ機能」と「ホログラム作成機能」を別のデバイスに任せることで、高解像度の映像で遅延なくディスプレイに表示する機能。
※いつの間にか「SpectatorView (Preview)」なるものが増えている！？今度やってみよう

# 実際にやってみる
## 環境

* Windows10
* Unity 2017.2.0f3 (64-bit)
* Microsoft Visual Studio Community 2017 Version 15.5.3

## 機材の準備
SpectatorViewをするには以下が必要

* PC
* 映像を出力できるカメラ
* キャプチャボード
* Hololensをがっちり支える冶具

### 映像を出力できるカメラ
以下を試してみた。

* gopro hero3+
* sony HDR-AS100V
* N3200

※全部うまくいったけど、[公式](https://github.com/Microsoft/MixedRealityCompanionKit/tree/master/SpectatorView#tested-cameras)が推薦しているのを使うのが無難だと思う。

### キャプチャボード
以下を試してみた

* IO DATA GV-USB3/HD
* Blackmagic Intensity Shuttle USB 3
* Elgato HD 60S

※「Elgato」だけうまくいった

### Hololensをがっちり支える冶具
[公式](https://github.com/Microsoft/MixedRealityCompanionKit/tree/master/SpectatorView#alternate-spectator-view-rig-setup)にならって（Alternateの方）、Amazonでポチる。全部で4000円ぐらい

## PCとHoloLensを開発者モードにしておく
![cal_05.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/61814723-1e66-1fca-7fcd-3f3fc1a3427b.jpeg)


## MixedRealityCompanionKitをクローンする
https://github.com/Microsoft/MixedRealityCompanionKit

## Caliblation
まずは、Calibrationを実施する（Hololensとカメラの位置関係のデータを取得する）
[Reedme](https://github.com/Microsoft/MixedRealityCompanionKit/tree/master/SpectatorView/Calibration)の通り進めていく

### 必要なソフトウェアをダウンロード
* OpenCV3.4.1をダウンロード

Elgatoを使う場合

* Elgato HD 60Sのドライバ
* [これ](https://github.com/elgatosf/gamecapture)をクローン

### チェックボードを印刷
以下のチェックボードを印刷し、クリアケースなどに入れる（しっかり平になればOK）
MixedRealityCompanionKit/SpectatorView/Calibration/CalibrationPatterns/2_66_grid_FULL.png

### 「dependencies.props」を編集
* Calibration用のプロジェクトを開く
<br>MixedRealityCompanionKit/SpectatorView/Calibration/Calibration.sln
* 以下の「OpenCV」と「Elgato」のパスを先ほどダウンロードした先にしておく
<br>MixedRealityCompanionKit/SpectatorView/dependencies.props
![cal_06.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/a4320457-245c-ed51-06e9-5d3971e83ee7.jpeg)

###「stdafx.h」の変更 
MixedRealityCompanionKit/SpectatorView/Calibration/Calibration/stdafx.h

* HoloLensのカメラをPCから利用するためにデバイスポータルの設定を「HOLOLENS_USER」「HOLOLENS_PW」を自分のものに変更しておく

* チェスボードの１つの”四角”のサイズ「CHESS_SQUARE_SIZE」を印刷したものにしておく（A3で印刷していればデフォルトで問題ないはず）
チェスボードの”四角”の個数が「GRID_CELLS_X」と「GRID_CELLS_Y」に記載されているものと異なる場合は変更する
* HoloLensをUSBで直接PCに接続していない場合は、「HOLOLENS_ADDRESS」をHoloLensのIPアドレスに変更しておく

### 「CompositorConstants.h」の変更
MixedRealityCompanionKit/SpectatorView/Compositor/SharedHeaders/CompositorConstants.h

* カメラから取得する画像が「1080P」でない設定にしている場合は「FRAME_WIDTH」「FRAME_HEIGHT」を修正する

* FrameProviderのタイプを設定する。
「USE_ELGATO」のみ「TRUE」にして他を「FALSE」にする（Elgatoを使う場合）

### カメラの画像出力設定
* goproのHDMI出力サイズを1080にする
* 念のため以下をつないで、Elgatoの「Game Capture HD」で確認
    * PC
    * Elgato HD 60S
    * gopro hero3+

映らない。。
![cal_08.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/eac4e64c-fcfc-009b-5b51-88cfadf33787.jpeg)


デバイスマネージャーで見たら、ドライバが入っていなかった。。
![cal_09.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/17bb97cd-f805-8d59-d975-d88931de2d93.jpeg)
ドライバをインストールしたら映った



### 「Calibration」実行する
早速怒られた
![cal_10.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/4ffca036-bc81-dac8-bc5b-db014cd31c76.jpeg)

CalibrationのプロパティでWindows SDKバージョンを変更する
![cal_12.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/a9f9dc6c-67f1-c1df-3256-9f3988437dda.jpeg)


再度実行したが、PC上にgoproの映像が表示されるもののHoloLensのカメラが反応しない。。（HoloLensのカメラで撮影するたびに白く光るはず）
ブラウザでDevice Portal（127.0.0.1:10080）を開いてみたが接続できなかった（USB経由でなくIPだといけた）
Windows SDKの「Windows IP Over USB」が入っていないのが原因だった。
![cal_17.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/79363161-819a-ea5f-5bb9-5a787264b0f0.jpeg)
「Windows IP Over USB」をインストールする
![cal_18.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/5c1b4a0e-e357-b866-8ce9-26a31281cc58.jpeg)

再度実行し、チェックボードをいろいろ動かし（HoloLensのカメラはgoproほど広角ではないのでちゃんとおさまるように動かす）、「Enter」を押す
Calibrationが成功すると「ドキュメント/CalibrationFiles」配下に、gproの写真とHoloLensカメラの写真とCalibrationData.txtが保存される。

## Conpositer

### 「CompositorDLL」と「UnityCompositorInterface」をビルドする
MixedRealityCompanionKit/SpectatorView/Compositor/Compositor.sln

### 「CopyDLL.cmd」をたたく
* 「MixedRealityCompanionKit/SpectatorView/SpectatorViewSample/Assets/」配下にもろもろコピーされる
![cal_19.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/71b40d23-a287-e0a4-c4c4-aa453a3ade7c.jpeg)

* 「CalibrationData.txt」は手動でコピーする（前はコピーしてくれたような。。）

## SpectatorViewPoseProvider
MixedRealityCompanionKit/SpectatorView/SpectatorViewPoseProvider/SpectatorViewPoseProvider.sln

* ビルドして、HoloLensに展開する（前はSpectatorView用のHoloLensアプリと体験用HoloLensのアプリは一緒だったような。。）


## SpectatorViewSample

* 「MixedRealityCompanionKit/SpectatorView/SpectatorViewSample/Assets/test.unity」を開く
* 「SharingToSVAdapter」の「Server IP」にPCのIPアドレス、「Spectator View IP」にHoloLensのIPアドレスを記載する
* ビルドしようとしたらUWPを選択できない。。。

![cal_20.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/d1ad3258-2426-e970-3930-7c0ffb547bd7.jpeg)

Unity初回起動時のライセンス設定をしていないのが原因だった。
![cal_21.jpg](https://qiita-image-store.s3.amazonaws.com/0/245808/69838a90-9ae5-13e5-a5dc-ed1372788336.jpeg)

* HoloLens上で「SpectatorViewPoseProvider」を実行させる
* test.unityの「Play」を実行する
* test.unityの「Spectator View」タブの「Compositor」で確認する
* できた！

# 参考
ありがとうございます。
https://www.naturalsoftware.jp/entry/2017/02/25/184758
http://2vr.jp/2017/07/01/setup-hololens-spectator-view/
http://mtholoblog.hatenablog.com/entry/2017/06/24/184722

## 他につまづいたこと

### キャプチャボード「IO DATA GV-USB3/HD」がうまくいかなかった
公式は特に推奨していないIO DATAさんのものを初め使ってみたが「Calibration」時に1080ではなく、480×640しか出力されなかった。ドライバを古いものにしてみたりしたが改善されなかった。

### キャプチャボード「Blackmagic Intensity Shuttle USB 3」がうまくいかなかった
BlackmagicのSDKをインストールしてみたが、カメラの映像を取得することができなかった。。。（引き続き調査）

### 「Calibration」の「OpenCVFrameProvider.h」のCAMERA_ID
ノートPC内蔵のカメラがCAMERA_ID=0となっていていつまでたってもgoproが認識されなかった。
デバイスマネージャーで内蔵カメラを無効にした

### 「Calibration」で「Enter」後に「100% Complete」後にエラー
どうしても「100% Complete」後にエラーになっていた。HoloLensかめらにチェックボードが一枚もおさまっていないのが原因だったっぽい