【Python/Open3D】点群のBoundingBoxを取得

# はじめに

前回、深度から点群に変換するところを、既存のデータセットを使って確認できました。
こんな感じの点群ができました。今日は、これを読んで大きさを計算してみます。

https://qiita.com/XPT60/items/60299e2a46976a2160ee

![スクリーンショット 2023-05-28 223946.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/4fe51b63-61b9-d8e6-5d5e-adfa13d1169c.png)


Open3Dを使って
- 点群を読む
- Bounding box の大きさを求めてみる
をやってみたいです。動作確認したのでメモリます。

# 内容

## ファイルの読み込み

Open3Dではファイルの拡張子から自動的に形式を判断して点群データを読み込んでくれるそうです。何と素晴らしい。

http://www.open3d.org/docs/latest/tutorial/Basic/file_io.html

```python
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

の２種類があるようです。

open3d.geometry.AxisAlignedBoundingBox　は、座標系の軸に沿った形でbouding box を作ります。

```python
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])
```

http://www.open3d.org/docs/latest/python_api/open3d.geometry.AxisAlignedBoundingBox.html



もうひとつの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)
```

こんな感じでした。

```python
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])
```

http://www.open3d.org/docs/release/python_api/open3d.geometry.OrientedBoundingBox.html


# まとめ

Bounding Boxの取得方法を確認しました。Visualize も試みたのですがエラーが出て描画ができないので、今回は見送りました。(涙)　
来週も生き延びらるかな。。。最近、生き延びて何になるのか、とも思うのだが。
(2023/5/28)