はじめに
前回、深度から点群に変換するところを、既存のデータセットを使って確認できました。
こんな感じの点群ができました。今日は、これを読んで大きさを計算してみます。
Open3Dを使って
- 点群を読む
- Bounding box の大きさを求めてみる
をやってみたいです。動作確認したのでメモリます。
内容
ファイルの読み込み
Open3Dではファイルの拡張子から自動的に形式を判断して点群データを読み込んでくれるそうです。何と素晴らしい。
In [1]: import open3d as o3d
In [2]: pcdfile = "./test.pcd"
In [3]: pcd = o3d.io.read_point_cloud(pcdfile)
In [4]: pcd
Out[4]: PointCloud with 267129 points.
Bounding Box を取得する
Bounding box を作る関数は用意されていて、Bounding box の種類は
- AxisAlignedBoundingBox
- OrientedBoundingBox
の2種類があるようです。
open3d.geometry.AxisAlignedBoundingBox は、座標系の軸に沿った形でbouding box を作ります。
axis_aligned_bounding_box = pcd.get_axis_aligned_bounding_box()
print(axis_aligned_bounding_box)
Bounding Boxの頂点や長さを取得てきます。
In [12]: axis_aligned_bounding_box
Out[12]: AxisAlignedBoundingBox: min: (-1.36644, -0.425714, -2.702), max: (1.043, 1.17087, -0.955)
In [13]: np.asarray(axis_aligned_bounding_box.get_box_points())
Out[13]:
array([[-1.36643994, -0.42571428, -2.7019999 ],
[ 1.04299617, -0.42571428, -2.7019999 ],
[-1.36643994, 1.17086661, -2.7019999 ],
[-1.36643994, -0.42571428, -0.95499998],
[ 1.04299617, 1.17086661, -0.95499998],
[-1.36643994, 1.17086661, -0.95499998],
[ 1.04299617, -0.42571428, -0.95499998],
[ 1.04299617, 1.17086661, -2.7019999 ]])
In [15]: axis_aligned_bounding_box.get_extent()
Out[15]: array([2.40943611, 1.59658089, 1.74699992])
min と max の間の長さが get_extend の値と一定します。
In [23]: axis_aligned_bounding_box.get_max_bound() - axis_aligned_bounding_box.get_min_bound()
Out[23]: array([2.40943611, 1.59658089, 1.74699992])
もうひとつのOrientedBoundingBoxは何かな、と思って見てみると以下のように書いてありました。
Computes the oriented bounding box based on the PCA of the convex hull. The returned bounding box is an approximation to the minimal bounding box.
主成分分析を使っているそうですが、要は点の分布の広がりのある軸を選んでいる、ということのようですね。
In [5]: oriented_bounding_box = pcd.get_oriented_bounding_box()
In [24]: oriented_bounding_box
Out[24]: OrientedBoundingBox: center: (-0.36581, 0.199845, -1.97165), extent: 2.74694, 2.07608, 1.5178)
こんな感じでした。
In [26]: oriented_bounding_box.extent
Out[26]: array([2.7469388 , 2.07608054, 1.51779647])
In [28]: np.asarray(oriented_bounding_box.get_box_points())
Out[28]:
array([[-1.30973102, 1.68483744, -2.63774606],
[ 0.98938256, 1.25122518, -1.19839554],
[-2.21900174, 0.09186567, -1.6652348 ],
[-0.81173094, 0.74143597, -3.71741995],
[ 0.57811192, -1.28514805, -1.30555817],
[-1.72100166, -0.85153579, -2.74490869],
[ 1.48738264, 0.30782371, -2.27806943],
[ 0.08011184, -0.34174658, -0.22588428]])
In [29]: oriented_bounding_box.get_max_bound() - oriented_bounding_box.get_min_bound()
Out[29]: array([3.70638438, 2.96998549, 3.49153567])
まとめ
Bounding Boxの取得方法を確認しました。Visualize も試みたのですがエラーが出て描画ができないので、今回は見送りました。(涙)
来週も生き延びらるかな。。。最近、生き延びて何になるのか、とも思うのだが。
(2023/5/28)