3D 点群をアノテーションする方法
ライダーやフォトグラメトリのデータに向き付き 3D 直方体でラベルを付ける。形式、詳細度、なぜ回転を四元数で持つべきか、そして 3D ボックスの一致度の測り方。
点群のアノテーションとは、疎で不均一にサンプリングされたデータ——遠方の物体は数十点の反射しかないこともある——の上に向き付きの 3D ボックスを置くことです。 難しいのは描画ではありません。ビューアを対話的に保つこと、アノテーターが自分の作業を確認する手段を与えること、そして往復に耐える回転表現を選ぶことです。
形式
| 形式 | 備考 |
|---|---|
KITTI velodyne .bin | 生の float32 の x, y, z, intensity。ヘッダーがないためレイアウトは仮定される |
| PCD | ascii、binary、binary_compressed(LZF) |
| PLY | ascii と両方のバイナリエンディアン |
| LAS | 1.0 から 1.4 |
.xyz / .pts | 一行につき x y z [r g b] |
| LAZ | 圧縮された LAS。先に変換:laszip -i scan.laz -o scan.las |
パースはブラウザではなくサーバー側で行ってください。形式が四つあるということは、エンディアンとレコードレイアウトのバグが四組あるということであり、しかもページ読み込みのたびに二百万点のスキャンを再パースすることになります。
対話性を保つ
生のスキャンは素朴に描画するには大きすぎます。実用的にするものが二つあります。
- 八分木による詳細度制御。 点は領域ごと、カメラからの距離ごとに読み込まれます。Potato では既定で有効です(
lod: true)。 - 間引きの上限(
max_points)。これはデータの設定ではなくビューアの設定として扱ってください。
この区別は一度実害を出したので繰り返す価値があります。かつて点ごとのセグメントラベルは間引き後の点群へのインデックスとして保存されており、max_points を下げると既存のラベルが黙って別の点を指すようになっていました。インデックスは常に元ファイルを参照すべきです。
アノテーターに 2D の確認手段を与える
40 メートル先の車は数十点の反射です。ボックスがぴったりか、長さは正しいか、回転は合っているかは、点群だけからはほぼ判断できず、カメラ画像なら一目瞭然です。
つまり、3D で編集し、2D で検証する。項目ごとにキャリブレーションを与え、すべてのボックスを各カメラビューに投影してください。それがなければ 3D のラベル付けにはフィードバックループがありません。周回カメラから正しく見えるボックスが、視線方向には数メートルずれていても、それを教えてくれるものが何もないのです。
正射投影のスラブパネルがもう半分を担います。精密な調整のための軸に平行な三つのビューで、完全にキーボードで操作できます。
回転は四元数で保存する
多くの形式は単一のヨー角しか保存しません。内部で完全な四元数を持つのは、往復で何かが失われるまでは過剰設計に見えます。
これにより KITTI のインポートが無損失になります。ヨーのみのフィールドが何も言わずに捨ててしまう、およそ 0.85 度のカメラ・ライダー間の取付傾斜も含めてです。KITTI への書き戻しではやはりピッチとロールを落とさざるを得ませんが、正しい振る舞いは、ボックスを黙って平坦化するのではなくどれだけの姿勢情報が捨てられたかを報告することです。
この落差は、保存層で黙って渡るのではなく、形式固有のコードで声高に渡ってください。
座標系こそが誤りの温床
間違えやすく、しかも気づきにくい三つの約束事があります。
- 参照座標系とカメラ座標系。 補正済みの参照座標系が必要なところでカメラの変換を使うと、すべてのボックスがそのカメラのステレオ基線分だけずれます。系統的で、数センチメートルで、アノテーターの雑さと取り違えられやすい誤りです。
- KITTI の location は底面であって中心ではありません。中心として読むと、すべての物体が自身の高さの半分だけ地下に埋まります。
- 寸法の順序と軸の割り当て。 ここでの 90 度の回転誤りは往復テストでは捕まりません。逆変換が同じ誤った仮定を置くため、両者が互いに整合してしまうからです。参照実装自身の頂点計算式と突き合わせて初めて捕まります。
一致度の測定
厳密な回転 3D IoU を使ってください。軸に平行な近似は水平な車載データには十分ですが、ドローン、手持ち、屋内スキャンでは誤りです。そこでは、アノテーターに由来するのではなく測度そのものに由来する不一致を報告してしまいます。
2D の場合と同様に問いを分けてください。アノテーターは同じ対象を見つけたか、同じラベルを付けたか、同じ位置に置いたか。バウンディングボックスの一致度を測る方法を参照してください。
設定
annotation_schemes:
- annotation_type: spatial_annotation
name: objects
description: "Put a 3D box around every vehicle and pedestrian."
source_field: point_cloud
calibration_field: calibration
tools: [cuboid_3d, point_3d]
labels:
- {name: car, color: "#FF6B6B", key_value: "1"}
- {name: pedestrian, color: "#FFD93D", key_value: "2"}
color_mode: height
lod: true
max_points: 400000
fit_box_height: true動作する例:KITTI のショーケース設計。
別のツールが正解である場合
Segments.ai、Kognic、Deepen AI、Supervisely、Xtreme1/BasicAI は専門ツールであり、実運用の自動運転パイプラインでは先を行っています。トラック伝播を伴う系列ワークフロー、レーダーとマルチ LiDAR、直方体の自動フィットモデル、Deepen の場合はターゲットレス較正の完全な製品まで揃っています。Supervisely と Xtreme1 は自前でホストでき、Supervisely ははるかに大きな点群を扱えます。
Potato は点群の系列を扱いません。アノテーションはフレームごとであり、スイープ全体にわたるトラック伝播は実装されていません。3D で Potato を選ぶのは、空間ラベルに対する信頼性統計が欲しいとき、あるいは 3D がマルチモーダル研究の一部であるときです。