備忘録：Open3DとPythonで点群を取得・表示する【Linux】

pythonで点群処理を行いたかったのですが、環境構築にかなり手間取ったので備忘録として残しておきます。

本記事執筆前の状況は次のような感じでした。
- 最新版のpython3(3.10.6)をダウンロード済み
- Open3dは未インストール
- 基本的にVScodeを用いてスクリプト開発
- Lidarや点群処理についての知識はほとんどなし


使用環境は以下のとおりです。
~~~
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.5 LTS
Release:	20.04
Codename:	focal
~~~
# ファーストテイク：動作せず
以下のページを参考にOpen3dをダウンロード
http://www.open3d.org/docs/release/getting_started.html
→ダウンロード中にエラーや警告発生（「pythonのファイルが古い」）
→一応Pythonファイル内で `import open3d` するも認識されない
__pythonのバージョン__ が悪さしているようです。
というわけでPythonのアップデートを中心に書いていきます。

# 準備
Pythonのアップグレード（ダウングレード）およびOpen3Dのインストールを行います。
## 各プログラムのアップデート
### 1. pip、numpyのアップデート
pythonをバージョンアップする前に、pipとnumpyをバージョンアップしておきます。
公式ドキュメンテーションによるとpipのバージョンは20.3以上である必要があるそうです（2022/9/6現在）。
また、numpyもOpen3Dに使用されるライブラリであり、古いと動作してくれません。
~~~
$ pip install --upgrade pip
$ pip install numpy --upgrade
#python3の場合はpip3
~~~

### 2. Pythonのバージョン確認
一番基本的ですが、見落としがちかもしれません。
というのも、Open3dをpythonで実行する場合、__正常に動作するpythonのバージョンが厳格に設定されている__ からです。
2022/9/6現在、Open3D 0.15.1が動作するPythonのバージョンは以下の範囲のみです。
- Python 3.6 ~ 3.9

これは使用するOpen3dのバージョンによって変わる可能性があるので、以下のURLより確認してください。
Open3D公式ドキュメンテーション : http://www.open3d.org/docs/release/getting_started.html

現在PCに入っているPythonのバージョンは、ターミナル上で次のように入力することで表示できます。
~~~
$ python -V
Python 2.7.15
$ python3 -V
Python 3.10.6
~~~
:::note info
これが先述したバージョンの範囲内（3.6~3.9）であれば飛ばしてください。
:::
私の場合は __pythonに2.7__ と、 __python3に3.10__ が適用されており、どちらもOpen3dの動作環境範囲外になっていました。
pythonが古いのはしょうがないにしても、__新しすぎても実行されない__ のは残念ですね。

### 3. pythonのアップデート
参考（Ubuntuでpythonのバージョンを切り替える）：https://qiita.com/piyo_parfait/items/5abbe4bee2495a62acdc

:::note warn
Pythonが新しすぎる場合も動かないので注意
:::
#### インストールされているpythonのバージョンと場所を確認
- python
~~~:pythonのインストール場所を確認
$　which python
/usr/bin/python
~~~
~~~:/usr/bin/以下の"python"と付くファイルを検索
$ ls /usr/bin/ | grep python
dh_python2
python
python2
python2.7
python3
python3-config
python3-futurize
python3-pasteurize
python3.8
python3.8-config
x86_64-linux-gnu-python3-config
~~~
- python3
~~~:python3のインストール場所を確認
/usr/local/bin/python3
~~~
~~~:/usr/local/bin/以下の"python3"と付くファイルを検索
python3
python3-config
python3.10
python3.10-config
python3.9
python3.9-config
~~~
たくさん入っていました。
今回は3.8がダウンロードされていたので、これをpythonに適用していきたいと思います。

#### update-alternativesによるバージョン管理
update-alternativeは、バージョンの優先順位を定めることができます。
~~~:update-alternativesによるバージョン管理
$ which update-alternatives     #update-alternativesが存在することを確認
/usr/bin/update-alternatives

$ sudo update-alternatives --config python               #pythonの優先順位を確認
update-alternatives: error: no alternatives for python    #まだ優先順位が登録されていない
~~~
~~~:python3.8を優先順位1で設定
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1    #python3.8を優先順位1で登録

$ update-alternatives --config python           #優先順位を確認
リンクグループ python に 1 つの alternative のみがあります (/usr/bin/python が提供): /usr/bin/python3.8
設定は行いません。
~~~
以上が問題なく実行されたら、最後にpythonのバージョンを確認してみましょう。
~~~:pythonバージョン確認
$ python -V
Python 3.8.10
~~~
無事にOpen3Dに適応したpythonバージョンに切り替えることができました。

:::note
筆者の場合、最初は設定されませんでしたが再起動したら通りました。
:::

### Open3Dのインストール
http://www.open3d.org/docs/release/getting_started.html
~~~:pipによるOpen3Dのインストール
$ pip install open3d

#python3の場合
$ pip3 install open3d
~~~
また、pythonのバージョンに合わせたい場合は以下のように書きます。
`38`(python3.8)の部分を`39`(python3.9)のように書き換えれば他のバージョンでも使えると思います。
~~~:Open3Dのインストール（python3.8の場合）
pip install --user --pre https://storage.googleapis.com/open3d-releases-master/python-wheels/open3d-0.15.1-cp38-cp38-manylinux_2_27_x86_64.whl
~~~
無事インストールできたかどうかは、以下のコマンドで確かめてください。
~~~:Open3Dインストールの確認
$ python -c "import open3d as o3d; print(o3d.__version__)"
0.13.0
~~~
私はpython3.8似合わせてインストールしたので、最新版(0.15)ではないバージョンがインストールされていますね。

## VS Codeでプログラミング

参考ページ：https://qiita.com/n_chiba_/items/fc9605cde5c19a8c7dad
参考スライド：https://www.slideshare.net/SSII_Slides/3d-101077557

ようやく環境設定が終わったので、さっそくプログラミングしてみましょう。
サンプルの点群データ（bun.pcd）を以下のページからスクリプトと同じファイルに保存してください。
https://github.com/sakizuki/SSII2018_Tutorial_Open3D/tree/master/data

点群データの画像表示を行うプログラムが下のとおりです。
わずか数行で書けてしまうのはすごいですね！
~~~py:点群データの画像表示を行うプログラム
import open3d #ライブラリのインポート

pointcloud = open3d.io.read_point_cloud("bun.pcd") #点群ファイルを変数pointcloudに保存
open3d.visualization.draw_geometries([pointcloud]) #点群を画像として表示
open3d.io.write_point_cloud("output.pcd", pointcloud) #output.pcbという名前の点群ファイルを出力
~~~
#### 実行結果
![Screenshot from 2022-09-06 12-40-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230173/3bac7e33-2e68-0ff2-b33a-58a92f3b7935.png)

:::note warn
注意
もしうまく行かない場合は、VS Codeに適用されているPythonのバージョンを確認してみてください。
右下の`Python ○○.○○.○○ 64-bit`から確認・変更できます。
:::

# まとめ、今後の発展
今回は点群処理ライブラリOpen3DをPythonにインポートし、点群を表示させるプログラムを作成しました。
今後は各種フィルタの作成やロボットの自立移動などを行っていきたいです。
最後まで読んでいただきありがとうございました。
修正・追記希望、間違いなどありましたらコメントお願いいたします。