Tangoの3DRをチューニングしてみた

Tangoには空間をスキャンして3Dメッシュを作成する3DRという機能があり、関連するパラメータもいくつかありますが、何を設定するとどう変わるのかが整理できていなかったので、ひと通り試してみました。


## 前提条件
Lenovo PHAB2 Proを使用しています。今後発売される他のデバイスでは、違った傾向が出るかもしれません。
測定に使ったアプリは、ExperimentalMeshBuilderWithPhysicsを一部改変したものです。

Tango AR Cameraに映像を投影した状態で前方の壁一面をキャプチャし、処理中のFPS、体感でのパフォーマンスを測定しました。

<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">Tangoの3DRをチューニング中。 <a href="https://t.co/S854dmJ6fP">pic.twitter.com/S854dmJ6fP</a></p>&mdash; jyuko (@jyuko49) <a href="https://twitter.com/jyuko49/status/836603482010329088">2017年2月28日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


## 設定項目

![スクリーンショット 2017-01-16 18.04.44.png](https://qiita-image-store.s3.amazonaws.com/0/153460/453d420f-2016-e632-1f65-cb05eae88ac7.png)

各項目の詳細は、[以前の記事](http://qiita.com/jyuko/items/5593db69981d714b495a)にも書いたので省略します。

## 結果
### Resolution
メッシュの細かさです。単位はメートルなので0.1で10cm、0.01で1cm単位の精度でメッシュを構築します。
値が小さくなると精度が増しますが、速度が落ちるというトレードオフが予想されます。

|Resolution|FPS|体感|
|:---|:---|:---|
|0.1|57-60|メッシュが粗く、キャプチャも遅い|
|0.05|52-55|メッシュがやや粗いが、キャプチャは速い|
|0.04|47-49|メッシュがやや粗いが、キャプチャは速い|
|0.03|43-46|メッシュは細かく、キャプチャも速い|
|0.02|35-37|メッシュは細かいが、キャプチャはやや遅くなる|
|0.01|3-17|メッシュはかなり細かいが、キャプチャは明らかに遅くなる|

結論から言うと、0.03-0.05の間でチューニングするのがよさそうです。
0.1-0.05だとFPSは出ていますが、メッシュが粗く感じる上、メッシュを大きく取っている分、キャプチャが遅くなります。また、メッシュに隙間ができやすくなります。
一方、0.03-0.01では、FPSが示す通り、パフォーマンスが著しく低下します。0.01にすると、リアルタイムでは使い物になりません。

この結果を受けて、以降の測定ではResolutionを0.03としました。


### Generate Color/Normals/UVs
メッシュにそれぞれの情報を付与するかどうかです。
付与した方が処理が増えるため、パフォーマンスの低下が懸念されます。

|Generate|FPS|体感|
|:---|:---|:---|
|すべてOFF|43-46|-|
|Color|34-37|キャプチャが遅くなったように感じる|
|Normals|42-46|体感ではほとんど変化がない|
|UVs|42-45|体感ではほとんど変化がない|

Colorを使う場合、Raw Bytes(ITangoVideoOverlay)の取得が必要です。
また、以前3DRのロジックを調査した中で、[Depth CameraとImage Cameraのデータが揃ってから処理をする](http://qiita.com/jyuko/items/ef35923806d7923f642c#gridindexarray%E3%81%AE%E6%9B%B4%E6%96%B0
)ようになっていたので、利用すると更新が遅くなります。
不要なら、チェックを外すべきでしょう。


### Space Clearing
メッシュ作成済みの空間に障害物が無くなっていたら、メッシュを上書きしてクリアするかどうか。
ONにした方が処理コストは増えるようです。

|Space Clearing|FPS|体感|
|:---|:---|:---|
|OFF|43-46|-|
|ON|42-45|体感ではほとんど変化がない|

大きな変化はありませんでした。
ただし、今回の簡易的な測定方法では、メッシュの除去が頻繁に行われていなかっただけという可能性もあります。


### Update Method
ヘルプによると、TRAVERSALを使うとメッシュの品質が良くなる分、処理コストがかかるそうです。

|Update Method|FPS|体感|
|:---|:---|:---|
|PROJECTIVE|43-46|-|
|TRAVERSAL|38-42|キャプチャが少し遅くなる|

確かに、TRAVERSALの方が処理コストは高いです。
メッシュの精度については、TRAVERSALの方が曲面が滑らかに見える気はするものの、所詮2-3cm単位のメッシュなので、あまり違いが無いようにも感じてしまいます。


### Mesh Min Vertices
メッシュを作る際の最小の頂点数です。
値が小さい方が、少ない頂点数でメッシュを作成するので、キャプチャが速く、処理コストが高いようなイメージがあります。

|Mesh Min Vertices|FPS|体感|
|:---|:---|:---|
|10|43-46|体感ではほとんど変化がない|
|20|43-46|-|
|50|42-45|体感ではほとんど変化がない|
|100|44-48|キャプチャがやや遅くなる|

空間あたりの頂点数はResolutionの値にもよるので、あくまでResolutionが0.03の場合ですが、10-50くらいまではあまり差を感じません。
100になると、メッシュを書くための頂点数が足りずに待ちが発生している印象を受けました。FPSが出ているのは、処理をしていない時間ができるためだと思います。


### Use Area Description Pose
最後に、Area Descriptionを使うかどうか。

|Use Area Description Pose|FPS|体感|
|:---|:---|:---|
|OFF|43-46|-|
|ON|42-45|体感ではほとんど変化がない|

座標系の原点が異なるだけなので、パフォーマンスへの影響は軽微だと思っています。


## まとめ
チューニングを試した結果、パフォーマンスに影響するポイントは以下になります。

* Resolutionを適切な値に設定する
* Generate Colorを使わない
* TRAVERSALを使わない
* Mesh Min VerticesをResolutionに対して適切な値に設定する

Resolutionを0.03にして、Generate ColorをOFF、PROJECTIVEにすれば、40FPS前後は確保でき、ほぼリアルタイムでメッシュを構築できると思います。
60FPSを維持したいなら、メッシュは粗くなりますが、Resolutionを0.05まで上げた方がよいです。

リアルタイムでは利用せず、メッシュを作成することが目的であれば、Resolutionを0.02にして、TRAVERSALを選択、Space ClearingをONにすると、より高品質なメッシュが構築できます。

## おわりに
調査動画で、[クエリちゃん SD版モデル](http://query-chan.com/download/)を使用しました。
[![02_クエリちゃんライセンスロゴ-e1472646888241-300x256.png](https://qiita-image-store.s3.amazonaws.com/0/153460/0e428400-07c9-17ff-fe29-6be7b7e51062.png)](http://query-chan.com/download/)