LiDARデータによる物体検出を試してみた-Part2
今回の内容
前回の記事でPointPilllarsの動作確認を行った。
次のステップとしてUnity上で自作のLiDARを実装して点群データを取得できるようにしたい。
今回は実装に入る前にPointPilllarsと前回使用したKittiDataSetについて深堀し、実装する際の要件を抽出する。
PointPillars
アルゴリズムそのものは理解しきっていない+既に良く解説されている記事が存在するのでリンクを張っておく。
ここでは前回利用したGitHubリポジトリで実装されているPointPilllarsの入出力形式についてまとめる。
入力形式
- (N,4)のfloat型点群配列 ※Nは点群数に依存
- コード上は上記の形式のnumpy配列をそのままtorchでTensorに変換して入力していた。
- N=2の場合のデータ構造の例は以下のようになる。
[[X座標1、Y座標1、Z座標1、反射率1]、[X座標2、Y座標2、Z座標2、反射率2]]
※注意:今回Kittiから取得した座標データをそのまま利用しており以下の座標系に従っている
出力形式
- 以下の構造のDict型オブジェクト ※Dは検出数に依存
キー | 形式 | 説明 |
---|---|---|
lidar_bboxes | (D,7) | 各検出オブジェクトの3Dバウンディングボックス |
labels | (D) | 各検出オブジェクトのラベル |
scores | (D) | 各検出オブジェクトに対する推論スコア |
lidar_bboxesについて
lidar_bboxesでは各検出オブジェクトの3Dバウンディングボックスを出力する。
各要素は以下のようになる。
0~2 | 3~5 | 6 |
---|---|---|
検出オブジェクト中心座標 | バウンディングボックスの矩形長さ | 物体角度 |
x,y,zにそれぞれ対応 | x,y,zにそれぞれ対応 | - |
また、リポジトリ内では可視化の前にデータ形式を(D,8,3)に変形していた。(bbox3d2cornersメソッド)
上記はバウンディングボックスの各頂点の3次元座標に対応する。
PointPillarsを最低限動かすための仕様
Unity
上記座標系に合わせたfloat型点群配列を取得可能
KittiDataSet
まずKittiDataSetについての論文はこちら。
PointCloudデータ
形式としてはPointPilllarsの入力と全く同じで以下となる。
- (N,4)のfloat型点群配列 ※Nは点群数に依存
座標系もまったく同様で以下となる。(というかKittiでPointPillarsを学習させているので当たり前。。)
データセットでは上記のデータをバイナリファイルで提供していた。
次にLiDARデバイス側のスペック依存の部分を以下に示す。
- 仕様デバイス:HDL-64E
- 回転:10Hz
- 垂直視野:26.9
- 垂直解像度:64
- 角度分解能:0.08度
- 1サイクル取得点群:平均10万ポイント
ちなみにメモとして16チャネルのVelodyneLiDARのマニュアル(P54で座標系について触れている)と実際にKittiで使用しているモデルの出てくる資料を張っておく
VelodyneLiDARのデータ構造
座標系はkittiに使われているものは以下
CameraImageデータ
カメラ自体は4台取り付けて取得したらしい(RGBとモノクロのそれぞれステレオ)
ちなみに3D物体検出ではP0~P3のカメラのうちP2を利用している。
画像は1382 x 512 pixels
Calibデータ
Kittiでは各データについてLiDAR座標をカメラ内の画像座標に変換するためのキャリブレーションデータを提供している。以下に内容を纏める。
-
P0~P3:4台のカメラそれぞれに対応するプロジェクション行列(射影行列)
ちなみにプロジェクション行列は同次座標系を使用する
→3次元座標にwを追加することで行列演算で平行移動を可能にしたもの
→各値からwを除算することで3次元座標に変換できる
https://xr-hub.com/archives/12124 -
R0_Rect:修正回転行列→複数のカメラ画像が同じ平面上に配置されるらしい
https://medium.com/test-ttile/kitti-3d-object-detection-dataset-d78a762b5a4 -
Tr_velo_to_cam:LiDAR座標系からカメラ座標系への変換行列?(おそらく回転情報も含む?)
https://www.cvlibs.net/datasets/kitti/setup.php -
Tr_imu_to_velo:IMU座標系からLiDAR座標系への変換行列?
KittiDataSet同様に可視化するための仕様
Unity側で映像出力する場合
Python
- 特になし
Unity
- 上記LiDARスペックにあう点群データを取得可能
- 検出したバウンディングボックスデータからカメラ座標へ変換可能(またはバウンディングボックスを直接生成)
Python側で映像出力する場合
Python
- Unity側のカメラキャリブレーションデータを反映させて射影変換し映像に検出結果を重畳可能
Unity
- 上記LiDARスペックにあう点群データを取得可能
- 同時に自信のカメラとLiDARの位置情報からキャリブレーションデータを生成可能
まとめ
上記内容から以下の仕様を満たす疑似LiDARをUnity上に実装していこうと思う。
(今回はリアルタイム性は一旦考えない)
Unity
1.座標系をPointPillarsに合わせた点群データを取得可能
2.何かしらの形式でファイル保存可能
3.検出データからバウンディングボックスを生成して可視化可能
Ex1.回転周波数、チャネル数、垂直画角、水平画角を調整可能
Ex2.LiDARの座標からカメラ内画像データに変換するためのキャリブレーション行列取得可能(PointPillar側の座標系に合わせる)
※Exの内容については理想形であり、今回は動作の確認を目的とするので実施しない
Python
1.csvに格納された点群データからPointPillarsを起動可能
2.検出した結果を別途ファイルに格納して保存可能
Discussion