3D Gaussian Splattingをubuntu22で試してみた。

## Gaussian Splattingの環境構築をできるだけはじめからていねいに
みんなWindowsで記事書いているので、せっかくだからubuntuでやってみた記事を書いてみた。

## 必要な環境
最低この環境が整っていれば記事に沿っていくだけでいいはずです。
- OS: Ubuntu 22.04
- GPU (私はNVIDIA GeForce RTX 2060)
- ビルドツール：cmake

詳しい情報は[README](https://github.com/graphdeco-inria/gaussian-splatting?tab=readme-ov-file)へ

---
<font color="Red">**既存のPython3やROS2入っている人でも大丈夫！**</font>
pyenvでcondaを構築します。

それでも嫌だという方は、Dockerへ。(ネットで非公式であがってた)

## 0. git clone
- git まだ入ってない方
```
sudo apt install git
```

- git clone
```
git clone https://github.com/graphdeco-inria/gaussian-splatting --recursive
```

https://github.com/graphdeco-inria/gaussian-splatting?tab=readme-ov-file

## 1. Nvidia Driver 535 Install
```
sudo apt install nvidia-driver-535
```
終わったら再起動。
BIOSで**secure boot**は**disable**になっていることを確認。
`nvidia-smi`が通ればOK

## 2. [Cuda 11.8](https://developer.nvidia.com/cuda-11-8-0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=22.04&target_type=deb_local) Install
公式そのままでは11.8が入らないので、こちらに書いたとおりに実行する。
重要なのは、最後のコマンドは必ず**cuda-11.8**で指定することです。
ちなみに、cudaを複数切り替えたい場合は[こちら](https://www.nemotos.net/?p=2374)を参考にする。
```
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin
sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda-repo-ubuntu2204-11-8-local_11.8.0-520.61.05-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2204-11-8-local_11.8.0-520.61.05-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu2204-11-8-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda-11.8
```

環境変数
```
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```

ここまで行って、`nvcc-V`が通ればOK

## 3. 破壊神Anaconda は直接入れたくないけど...
**<font color="Red">あなたの環境に応じてAかBかCを選んでください！</font>**

**A. Anacondaを直接入れても大丈夫**
終わったら4章へ

https://ja.linux-console.net/?p=14958

**B. Anacondaは構築済み**
3章は飛ばして4章へ

**C. Anacondaを直接入れたくない！（既存のpython環境壊したくない、ROS2入っている）**
筆者はros2の環境が構築済みであり、競合を避けたいためcondaを直接入れたくありませんでした。
そこで、以下に沿ってpyenv経由でcondaを入れましょう。

（補足）pyenvとは？
- pyenvではpythonのバージョンを簡単に切り替えられます。
- anacondaも利用できる。
- また、virtualenvを用いると簡単に仮想環境に入ることができます。

### 3.1 現在のpythonのバージョンを控えておく
```
python3 --version
```
ここで表示されたバージョンを```<original python version>```とします。 例：`3.10.4`
pyenvでinstallして、pythonのバージョンを``<original python version>``にする。

### 3.2 pyenvをinstall
```
~$ sudo apt update
~$ sudo apt install build-essential libffi-dev libssl-dev zlib1g-dev liblzma-dev libbz2-dev \
  libreadline-dev libsqlite3-dev libopencv-dev tk-dev git
~$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```
### 3.3 bashrcに書き込む
```
~$ echo '' >> ~/.bashrc
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
~$ source ~/.bashrc
```

### 3.4 virtualenvをinstall
```
~$ git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
~$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
~$ source ~/.bashrc
```

### 3.5 仮想環境でのconda構築
#### 3.5.1 既存のpythonのバージョンをpyenv入れる
今まで入っていたpythonのバージョンをGlobalに適応します。
```
pyenv install <original python version>
pyenv global <original python version>
```

<font color="Red">注意：
元々入っていたpythonのバージョンでpip installしたものは引き継がれるわけではないので、改めてinstallする必要はある。
ただ、（あまりかっこよくないけど）`~/.bashrc`の下記の部分をコメントアウトすればまた元の環境で作業することができる。</font>
```
# export PYENV_ROOT="$HOME/.pyenv"
# export PATH="$PYENV_ROOT/bin:$PATH"
# eval "$(pyenv init -)"
# eval "$(pyenv virtualenv-init -)"
```

#### 3.5.2 conda構築
以下の作業では(仮想環境名)が出てくるのでそれも表示しています。
$マークの後を入力してください
```
~$ pyenv install -l | grep anaconda
~$ pyenv install anaconda3-2023.09-0
~$ pyenv global anaconda3-2023.09-0
(anaconda3-2023.09-0)~$ conda create -n gs_conda python=3.7.13
(anaconda3-2023.09-0)~$ pyenv global <original python version>
~$ cd gaussian-splatting
~/gaussian-splattin$ pyenv local anaconda3-2023.09-0
(anaconda3-2023.09-0)~/gaussian-splattin$ conda activate gs_conda
(gs_conda)(anaconda3-2023.09-0)~/gaussian-splattin$ python --version
```
(補足)
condaコマンドがpyenv globalでanacondaに設定されていないと通らないので、上記のようなステップを踏んでいます。

## 4. gaussian_splattingの仮想環境を構築
$マークの後を入力してください。
（※三章行った人向けの()は以下では省略しています）
```
($ cd gaussian-splatting)
~/gaussian-splatting$ conda env create --file environment.yml
~/gaussian-splatting$ conda activate gaussian_splatting
```

**表示確認**
- 3章を飛ばした方は以下となればOK
```
(gaussian_splatting)~/gaussian-splatting$
```
- 3章を行った方は以下でOK
```
(gaussian_splatting)(anaconda3-2023.09-0)~/gaussian-splatting$
```

## 5. Train
まずは、[githubのREADME](https://github.com/graphdeco-inria/gaussian-splatting?tab=readme-ov-file)に貼られている`T&T+DB COLMAP(650MB)`をとってきます。
![gaussian_splatting_train.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1294864/e572a893-c0ee-00da-6fe7-63039caa3bee.png)

続いて、train。
`<path to COLMAP>`には`home/yourname/tandt_db/tandt/train`を入れてみました。
鉄道なのか学習なのかよくわかりません。

```
~/gaussian-splatting$ python train.py -s <path to COLMAP>
```
結構時間がかかるので、寝ました。

学習が終わると、`gaussian_splatting/output`にランダムな文字列でフォルダができる。
ちょうどコマンドの出力に`Output folder: ./output/a7c2cf38-f`と書いてありました。
以降`<path to trained model>`はこのフォルダのパスを示します。

### 5. GUI
### 5.1 Build
```
~$ sudo apt install -y libglew-dev libassimp-dev libboost-all-dev libgtk-3-dev libopencv-dev libglfw3-dev libavdevice-dev libavcodec-dev libeigen3-dev libxxf86vm-dev libembree-dev ninja-build
~$ cd gaussian-splatting/SIBR_viewers
~/gaussian-splatting/SIBR_viewers$ cmake -Bbuild . -DCMAKE_BUILD_TYPE=Release
~/gaussian-splatting/SIBR_viewers$ cmake --build build -j24 --target install
```
### 5.2 Run
```
~/gaussian-splatting/SIBR_viewers$ ./install/bin/SIBR_gaussianViewer_app -m <path to trained model>
```
以下が出てきたらOK。（写真の画面はこれ以上大きくできなかった）

![Screenshot from 2023-12-10 12-40-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1294864/56019040-c2f5-a10d-5cb1-f035ebfc0954.png)


### 5.3 操作
画像の部分を一度クリックします。
READMEのNavigation in SIBR Viewersにおいて、キーボードの
`W, A, S, D, Q, Eでカメラの視点、I, K, J, L, U, Oで回転します。`と書いてありました。
`P`で視点がリセットされました

また、Camera Point viewを`Interp.`にすると、勝手にいい感じに視点をあちこち切り替えてくれます。

### 5.4　詳細なセッティング
Scaling Modifierをいじるとシャープネスが変えられるそうです。
中間くらいにすると、ガウシアンがくっきり見えてきて、0にすると点群になります。
![Screenshot from 2023-12-10 13-21-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1294864/14d7e8ba-1d26-3df6-ebe5-b7ebee4a2a08.png)

### 5.5 Render Mode
Render Modeを切り替えると元の点群とかも表示されます
- Initial Points
この点群はoutputのplyに入ってますね。
![Screenshot from 2023-12-10 13-21-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1294864/348313ee-ca3c-036a-010f-f52cc71c8914.png)

- Ellipsoids (重い)
![Screenshot from 2023-12-10 13-22-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1294864/3a1352ee-1c5c-d527-1e5b-6f90895b0945.png)

## 6. 自分で用意したデータを使いたい場合
### 6.1 3Dモデル化したいものをぐるっと一周映すように動画を用意します。
### 6.2 動画から静止画
ffmpegをインストール 
```
$ sudo apt install ffmpeg
```

test_data（名前は何でも良い)と、その中にinput(必ずこの名前)のフォルダを作ります。

```
$ mkdir test_data && cd test_data
~/test_data $ mkdir input && cd input
```
以下のコマンドで動画から写真化できます。
inputの中に写真を保存するようにしましょう。q:vは1が最高画質です。
```
~/test_data/input $ ffmpeg -ss <開始時間[s]> -i path_to/video.mp4 -t <切り出し時間[s]> -r <1sに何枚切り出すか> -q:v <画質クオリティ1~4> -f image2 %06d.jpg
```
例：
```
~/test_data/input $ ffmpeg -ss 0 -i path_to/video.mp4 -t 60 -r 4 -q:v 1 -f image2 %06d.jpg
```

### 6.3 COLMAPのデータセットを作る
※仮想環境の()は省略
```
$ cd gaussian-splatting
~/gaussian-splatting $ conda activate gaussian_splatting
~/gaussian-splatting $ python convert.py -s '~/test_data'
```

### 6.4 Train
```
~/gaussian-splatting $ python train.py -s '~/test_data'
```

### 6.5 GUI
```
~/gaussian-splatting $ cd SIBR_viewers
~/gaussian-splatting/SIBR_viewers $ ./install/bin/SIBR_gaussianViewer_app -m <path to trained model>
```

## 7. (何かあれば更新します)

## 9. 補足
### 9.1 condaの開始と終了
もう一度gaussian_splattingの仮想環境をactiveに
```
conda activate gaussian_splatting
```
終了
```
conda deactivate
```

### 9.2 pyenvで構築できる環境一覧
```
pyenv install -l
```
anacondaのみ表示する場合
```
pyenv install -l | grep anaconda
```

### 9.3 pyenvのinstall済みのバージョンと、現在の環境を確認
```
pyenv versions
```

## 10. おわりに
gaussian-splattingはREADMEがしっかりしていたので、自分で動かすことができました。
ただ、学習系の手法を動かすのはこれが初めてなので、何か間違ったステップを踏んでいるかもしれません。
もし、修正または追加したほうがいいということがありましたら、ご気軽に編集リクエストしていただければと思います。