tks_yoshinagaの日記

KinectやLeap motion, VRやARなどの技術を使ってやったことのメモとか

C#で始めるAzure Kinect開発⑥:Unity+C#でPoint Cloud表示

1. はじめに

前回はUnityでAzureKinectを使うためのセットアップ手順について解説しました。今回はその続きとして、Depthとカラー画像を取得し座標変換で得られる色付きのPoint Cloudを表示する方法について解説します。

f:id:tks_yoshinaga:20191205180304j:plain


まずは下記で作成したプロジェクトをUnityで開きましょう。

 

 2. 点群表示の準備

1) 点群描画用のマテリアル&シェーダをダウンロード [Link]
2) ダウンロードしたPointCloud.unitypackageをダブルクリック
3) 前回作成したUnityプロジェクトに取り込む。
4) Hierarchy内のAzureKinectオブジェクトをクリックして選択
5) Inspector内のAdd Componentをクリック

f:id:tks_yoshinaga:20191206085237p:plain

6) meshで検索しMeshFilterをクリック
7) 再びInspector内のAdd Componentをクリック
8) 今度はMeshRendererをクリック

f:id:tks_yoshinaga:20191206085131p:plain


9) AzureKinectオブジェクトのInspectorに注目
10) 追加されたMeshRenderer内のMaterialsを開く
11) Element0の横の枠の中にAssetsフォルダ内のPointCloudドラッグ&ドロップ

f:id:tks_yoshinaga:20191206085704p:plain

 

3. C#スクリプトを記述

3.1. 変数やメソッドの準備

1) Kinectのデータを非同期で取得するためusingでTasksを読み込む
2) Point Cloudの全点数や頂点・色、表示用オブジェクトの変数を追加
3) 座標変換のためのクラスを使用するためtransformationを追加
4) PointCloudを表示するオブジェクトを作るInitMeshメソッドを追加
5) Kinectからのデータ取得とPointCloud描画のためのKinectLoopメソッドを追加
6) StartメソッドでInitMeshKinectLoopを呼び出す

gist.github.com

3.2. 座標変換のための情報を取得

InitKinect内、kinectの動作モード設定の後にCreateTransformationで座標変換に必要な情報を作る

gist.github.com

3.3. Point Cloud描画の準備

1) Depth画像の縦・横の画素数からPointCloudの点数を算出
2) Meshをインスタンス化し、一度に描画できる点数の上限を大きくする
3) 頂点・色・描画する点のリストindicesを初期化
4) 描画するvertices内の点の番号をindicesに代入(全部描画)
5) 頂点・色・描画する点のリストを用いてmeshを初期化
6) Unityで作ったAzureKinecオブジェクトのMeshFilterとスクリプト上でのmeshとを関連付ける

gist.github.com

3.4. Kinectのデータ取得とPointCloud描画

1) whileでKinectからデータの取得とPointCloud描画を継続
2) GetCaptureKinectからデータを取得
3) ColorImageToDepthCameraでDepth画像との位置合わせ済みのカラー画像を取得
4) GetPixelsによって各ピクセルの色情報のみの配列を取得
5) DepthImageToPointCloudでDepth画像をxyz座標に変換
6) GetPixelsで各点の3次元座標のみの配列を取得
7) for文で1ピクセルずつ対応する3次元座標と色を描画用配列に代入
8) 最新の点と色の配列をmeshに代入

gist.github.com

9) Ctrl + Sで保存
 ※完成版のソースコードこちら

4. Unityで動作確認

1) Unityエディタに戻り実行
2) Sceneタブをクリックしマウス操作で視点を変更しながら3次元的にデータが取れていることを確認

f:id:tks_yoshinaga:20191205175648j:plain

5. まとめ

今回は3次元のPoint Cloudを描画する手順を紹介しました。基本的にはこれまでの記事と同様の手順となりますが、主な相違点としてはDepthImageToPointCloudでDepthをxyzの3次元の点に変換をしている事、そしてその値の代入先が画像ではなくメッシュの頂点verticesと対応する色を格納するcolorsである事の2点です。この結果を用いてVRやARでPoint Cloudを表示することも可能なので興味があればトライしてみてください。

 

AzureKinectの他の記事はこちら!

tks-yoshinaga.hatenablog.com