GoogleMapsのポリゴンデータを取り出してPointCloud化する方法



#はじめに
GoogleMapsの都市モデルってかっこいいですよね！
今回はフォトグラメトリ(Photogrammetry)という手法を使ってポリゴンおよびポイントクラウド情報を取り出す方法をご紹介します。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Polygon → Camera Depth Point Cloud → Point Cloud<a href="https://twitter.com/hashtag/touchdesigner?src=hash&amp;ref_src=twsrc%5Etfw">#touchdesigner</a> <a href="https://twitter.com/hashtag/realtime?src=hash&amp;ref_src=twsrc%5Etfw">#realtime</a> <a href="https://twitter.com/hashtag/pointcloud?src=hash&amp;ref_src=twsrc%5Etfw">#pointcloud</a> <a href="https://t.co/8iVGfaN20j">pic.twitter.com/8iVGfaN20j</a></p>&mdash; ツミキルーム\Takashi Kawamura (@tsumiki_room) <a href="https://twitter.com/tsumiki_room/status/1188630895395164161?ref_src=twsrc%5Etfw">October 28, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

####フォトグラメトリとは 
>被写体をさまざまなアングルから撮影し、そのデジタル画像を解析、統合して立体的な3DCGモデルを作成する手法です。デジタルカメラを用いた3次元測定機に応用されています。フォトグラメトリーは3Dスキャナのような特殊な機器が不要で、通常の写真だけで生成できることが特徴です。一般的には110枚程度の画像データが必要となり、都市や建築物などの大きなものまで3Dモデルとしてデータにできます。
[https://school.dhw.co.jp/word/cg/photogrammetry.html](https://school.dhw.co.jp/word/cg/photogrammetry.html)　から引用

ネットで入手できる作成ツールがいろいろありますが、今回は無料の作成ツール[MeshRoom](https://alicevision.org/)で作成し、描画は[TouchDesigner](https://derivative.ca/)を使いたいと思います。

+ MeshRoom  ─　[https://alicevision.org/](https://alicevision.org/)
+ TouchDesigner ─　[https://derivative.ca/](https://derivative.ca/)

##1.Google Mapsで素材を取得する
######1.1 GoogleMapsの3D化したいエリアを開き、余計な表示を消しておく

+ 地図表示から航空写真表示にする
+ 検索ボックス内にあるハンバーガーメニューを開いて航空写真の”ラベルを表示”をクリックする
+ 画面左のパネルを折りたたむ

するとこんなふうにすっきりした航空写真になります
![googleMaps1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/9fa337a3-adf1-6541-d6ca-d39f9c8696ac.png)

######1.2 あとはひたすらにスクリーンキャプチャする

左クリック ─　縦横移動
ctrl+左クリック　─　回転
中ホイール　─　ズーム
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/ce389f07-5b60-d7e9-91b5-6111d81691cd.png" width=50%>

こんな感じでエリアをまんべんなくキャプチャしていきます。
適切な枚数はエリアのサイズによって異なりますので、一度100枚程度で試してみてから精度が低い部分を追加で撮影するのがコツかなと思います。
当然枚数が増えると精度が増しますが、そのぶんMeshRoomでの計算に時間がかかります。


######1.3 書き出した画像の無駄な部分をトリミングする
画面キャプチャした際に発生した無駄な部分（ウィンドウ枠など）をトリミングしていきます。
方法はいろいろあると思いますが、僕は以下の方法でおこなっています。

1. Adobe Bridgeで連番入りのファイルネームにリネーム
2. Adobe AfterEffectsで矩形にトリミングしてフレーム単位の連番書き出し

<br>
<font color="MediumVioletRed">**これでMeshRoomで処理するための画像の準備が整いました！**</font>
<br>
##2.MeshRoomを使ってPointCloudデータとポリゴンデータを生成する
#####2.1 MeshRoomを起動して、書き出したキャプチャを読み込みプロセスを実行する
1. 画面左側の"images"に画像をドラッグ＆ドロップするとファイルが読み込まれる
2. ファイルを一旦保存する
3. 上部中央緑色のの"Start"を押してプロセスを実行する
<br><br><br>
画像枚数によって異なりますが、プロセスが終了するまで数時間待つこともあります。
ファイルを保存した場所に各ノードのディレクトリが生成されるので、実行前に必ず保存しておきましょう。

![Untitled - Meshroom 2019.2.0 2019_12_20 15_54_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/915ee0ea-e198-2f62-79c4-27c6548d1025.png)
<br><br>


生成結果はこんな感じです。大量のカメラとポイントクラウドが生成されました。
Y平面の角度が斜めになっていて扱いにくそうですが、それはこの後TouchDesignerで直すことにします。
![pointcloud view.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/4d2b4338-1414-9d2a-565b-58f738464ca5.png)

#####2.2 ポリリダクションする
**──ポリゴンデータを使いたい人用の工程です。PointCloudのみ使用したい場合はこの項目を読み飛ばしても構いません。**

まずはポイントクラウドからポリゴンデータを取り出してみます。
ただポリゴン数が多すぎるとこの後なにかと面倒なのでポリリダクションしておきます。

1. "Graph Editor"の"Texturing"ノードを選択し、"3D Viewer"中央下部にある"Load Model"をクリックしてメッシュデータを表示させる
2. "Meshing"ノードを選択し、"Max Points"パラメータの値を5～10分の1程度に下げる
3. 再度"Start"を押して処理を実行する
　
　
<br><br><br>
"Graph Editor"です。各ノードを選択することでプロセスを細かく設定することができます。
![node.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/cf98a301-dd7e-7b7d-d381-aa5271446919.png)
<br><br><br>

<b>右/約500万ポリゴン(減ポリ前)、左/約100万ポリゴン(減ポリ後)<b>　

若干ディテールが削られているのがわかると思います
用途にあわせて適切なリダクションをしましょう
![hilomesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/204b44e9-5ee6-632b-11c0-9b6d997739fc.png)
<br><br>

#####2.3 ポイントクラウドとポリゴンデータを取り出す
MeshRoomのディレクトリから必要なモデルデータを取り出します。
![wipe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/8b4865e4-661e-51be-1016-3b1cede2e80d.png)


* ポリゴン　─　MeshroomCache\Texturing\　以下フォルダ内の.obj
* pointcloud　─　MeshroomCache\PrepareDenseScene\ 　以下フォルダ内の.abc(alembic)



<br>
<font color="MediumVioletRed">**書き出せました！あとはTouchDesignerで描画するだけです**</font>
<br>
##3.TouchDesignerを使ってPointCloudを描画してみる

今回は取り出したalembicをTouchDesignerで描画してみたいと思います。
現状experimental版のみTOPを使ってインスタンス化することができます。
なのでexperimental版の使用を推奨します。
通常版を使う場合はglsl MATでインスタンス化する必要があります。

#####3.1 alembicから座標と色を取り出す
alembicには頂点カラーと頂点座標、さらにスキャンに使った大量のカメラ情報が入っています。
今回必要なのはカラーとポジションなので、それを取り出します。

1. alembicをエディタ上にドラッグ＆ドロップする、もしくはalembic SOPで読み込む
2. transform SOPで地面をXZ平面と地面の位置を揃える(目合わせ)
3. SOP to CHOPでCHOP化し、"Position XYZ"と"Color RGB"を"ON"にする


![alembicNode.PNG](https://qiita-ima![shuffle.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/09a524dd-d7ee-2a21-c544-513bdcb22204.png)
ge-store.s3.ap-northeast-1.amazonaws.com/0/152366/b78dd4ed-c475-9fba-1537-346594b19f39.png)

<br>インスペクタの中身はこんな感じです
![sopTo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/e431d477-6434-4dab-a8ca-002d5437903f.png)


#####3.2 カラーと頂点のCHOPを2次元画像にする
そのままgeo COMPに入れても描画されるのですが、より軽くてより扱いやすくするためにTOPにしてからインスタンス化します。

1. 全6チャンネルをそれぞれselect CHOPで分ける
2. shuffle CHOPで2次元配列にする
3. CHOP to TOPで画像化する
4. reorder TOPでカラーとポジションそれぞれをRGB画像にまとめる

<br><br>
こんなふうにselect CHOPで小分けにして、shuffle CHOPで配列にして、CHOP to ToPで画像化したものをreorder TOPでまとめます
![shuffle.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/9b082c1c-5de0-0a49-2762-17eca7e01cb3.png)
<br>
Shuffule CHOPのインスペクタはこんなかんじ
Methodを"Split N Samples"にして"N Value"を1000くらいにしておきます
![shuffle_ins.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/6df9104c-5867-5c8b-4cc3-65b544db3d1a.png)

<br>
できたテクスチャをreorder TOPでRGB画像にまとめます
![reorder.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/0d9b57e9-be3a-c801-2c44-e3983f178a10.png)



#####3.3 geometory COMPでインスタンス化する

あとはそれぞれのテクスチャを使ってインスタンスするだけです。
テクスチャのRGBをそれぞれの座標や色に置き換えていきます。ここまでくればいつものインスタンス化のプロセスと同じですね。
<br>
geometory COMPのインスペクタ
テクスチャのRGBを使ってインスタンスの指定したいので”r”と”g”と”b”で各数値を指定します
![geo1geo2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/3ea7ba31-4e62-c092-71da-2542883198f2.png)


#####3.4 インスタンス化するテクスチャやオブジェクトを工夫してみる
カラーと座標を使ってパーティクルを配置/着彩するところまでできました。
複製するオブジェクトやテクスチャを工夫して個性豊かなポイントクラウドを作ってみましょう！

<br>
板ポリとノーマルマップを使って球体風にしたもの
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/touchdesigner?src=hash&amp;ref_src=twsrc%5Etfw">#touchdesigner</a> <a href="https://t.co/PxKHkUxzf5">pic.twitter.com/PxKHkUxzf5</a></p>&mdash; ツミキルーム\Takashi Kawamura (@tsumiki_room) <a href="https://twitter.com/tsumiki_room/status/1187991551042916353?ref_src=twsrc%5Etfw">October 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<br>
アルファ抜きした板ポリでアイコン風にしたもの
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Symbolized city<a href="https://twitter.com/hashtag/touchdesigner?src=hash&amp;ref_src=twsrc%5Etfw">#touchdesigner</a> <a href="https://twitter.com/hashtag/dotfes2019?src=hash&amp;ref_src=twsrc%5Etfw">#dotfes2019</a> <a href="https://t.co/Yt7YeHY4dn">pic.twitter.com/Yt7YeHY4dn</a></p>&mdash; ツミキルーム\Takashi Kawamura (@tsumiki_room) <a href="https://twitter.com/tsumiki_room/status/1191209487555649536?ref_src=twsrc%5Etfw">November 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



#最後に
TouchDesignerのソースをgithubにあげたのでこちらも参考にしてみてください
https://github.com/tsumikiroom/pointcloud

ごく当たり前ですが、本来フォトグラメトリとは実際にカメラで撮影したものをモデル化する手法なので、今回のようにgoogle Mapsをキャプチャするほうが特殊な使い方です。もちろん同じプロセスで普通のフォトグラメトリもできますので、そちらもチャレンジして頂けると表現の幅が広がっていいんじゃないかと思います。