mmdetection3dを試す

# 概要

最近、3次元点群処理にはまっています。色々と調べる中で[mmdetection3d](https://github.com/open-mmlab/mmdetection3d)というOSSのツールが使いやすかったのでその導入方法と簡単な使い方を紹介したいと思います。

## mmdetection3dとは

OpenMMLabが提供する3次元物体検出のためのライブラリ、ソフトウェアです。OpenMMLab自体はPytorchをベースとしたコンピュータビジョンアルゴリズムを幅広く包括するフレームワークのような位置づけで、ほかにも2D物体検出向けのmmdetectionなどが提供されています。

https://github.com/open-mmlab

以下のように有名どころの学習済みモデルが一通りそろっているのですぐ試せるのが魅力的です。

https://github.com/open-mmlab/mmdetection3d

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84781/516ee9bf-3a77-422c-aea5-a1dc2dcb22ae.png)

## 導入

### 前提条件

* 使用するmmdetection3dはv1.0.0rc6です。
* Dockerコンテナー上で動かします。
* Open3DによるGUI表示に対応します。
* 今回はCenterPointアルゴリズムを動かすところまでやります。

### 実行環境

* ホストPCのスペック
    * Ubuntu22.04
    * CPU Intel Core i5 12400F
    * GPU RTX 3060
    * Memory 64GB
* 必須ソフトウェア
    * NVIDIAドライバー
        * 今回はver 530.30.02を使用した。
        * 公式サイトを参考に`cuda-drivers`をインストール
            * https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html
    * NVIDIA container-toolkit
        * 公式サイトを参考にインストール
            * https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker
        * CUDAコンテナーが動くことを必ず確認しておいてください。
    * 注意
        * この方法は現時点(2023/3/5)のインストール方法。
        * この辺のインストール方法は頻繁に変わるため、インストールする場合は常に公式サイトを確認する。
### NuScenesデータセットの用意

CenterPointはNuScenesデータセットのみに対応しているため公式サイトからダウンロードしておく。
今回ダウンロードするのはFull dataset(v1.0)項目にあるMiniにします。
ダウンロードしたデータセットは後で使うときのために`~/`直下に置き解凍しておきます。

https://www.nuscenes.org/download

### docker build

以下のDockerfileを作成します。ベースイメージは環境ごとに適宜変更してください。今回はRTX3000シリーズのGPUを載せているのでCUDA11以上が必須になります。
* メモ
    * ベースイメージによってはdocker build時にGPGエラーが発生して途中で止まる。
        * その場合、<https://zenn.dev/takakurasato/scraps/d3e0ee6132a5c5>を参考にして解決する。
    * Pythonは3.9以下のバージョンを使用すること。
        * 現時点(2023/3/5)ではバージョン3.9以上だと一部プログラムでエラーが発生する。
        * 今回Dockerfileで定義したベースイメージはバージョン3.8.12を使用している。
        * pythonの`networkx`ライブラリをver2.5に上げればpython3.9以降でも動作します→[参考記事](https://qiita.com/np_hsgw/items/c2cdd4876d2bc72d776c)
```Dockerfile
FROM pytorch/pytorch:1.11.0-cuda11.3-cudnn8-runtime
RUN apt-get update && apt-get install -y \
    ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libxrender-dev \
    libgl1 libgomp1 build-essential wget \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN pip install open3d
RUN pip install openmim
RUN mim install mmcv-full mmdet mmsegmentation
WORKDIR /workspace
RUN git clone https://github.com/open-mmlab/mmdetection3d.git
WORKDIR /workspace/mmdetection3d
RUN mkdir checkpoints
# デモプログラム用の学習済みモデルをダウンロード
RUN wget -P ./checkpoints/ https://download.openmmlab.com/mmdetection3d/v0.1.0_models/second/hv_second_secfpn_6x8_80e_kitti-3d-car/hv_second_secfpn_6x8_80e_kitti-3d-car_20200620_230238-393f000c.pth
# CenterPoint用の学習済みモデルをダウンロードしておく
RUN wget -P ./checkpoints/ https://download.openmmlab.com/mmdetection3d/v1.0.0_models/centerpoint/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus_20220810_030004-9061688e.pth
RUN pip install -e .
```

`docker build`は例えば以下のようなコマンドで実行します。

```bash
docker build -t mmdet3d -f docker/Dockerfile .
```
### docker run

buildが正常に終了したら`docker run`を実行します。
ただし、その前にGUI表示のための設定を追加します。
参考 [Open3Dの公式サイト](http://www.open3d.org/docs/release/docker.html)

```bash
xhost local:root
docker run -it --rm --gpus 'all,"capabilities=compute,utility,graphics"' -v /tmp/.X11-unix:/tmp/.X11-unix -v /home:/home -e DISPLAY mmdet3d bash
```

### デモプログラムの実行

問題なくコンテナーに入れた場合`/workspace/mmdetection3d`ディレクトリにいるはずです。
そのまま以下のコマンドを入力し、Open3DのGUI画面が表示され点群とバウンディングボックスが表示されたら正常に動作しています。
マウスやキーボードで拡大縮小、平行移動ができます。
終了は`q`キーを押すことでできます。

```bash
python demo/pcd_demo.py demo/data/kitti/kitti_000008.bin configs/second/hv_second_secfpn_6x8_80e_kitti-3d-car.py checkpoints/hv_second_secfpn_6x8_80e_kitti-3d-car_20200620_230238-393f000c.pth --show
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84781/4668bc22-089a-8810-fdcd-5b4b057f2fdd.png)

## 学習済みモデルで推論

NuScenesデータセットと学習済みモデルを使って推論を行います。

まずデータセットをmmdetection3dが読み込めるように変換するスクリプトを実行します。
`./data/nuscenes`ディレクトリ以下にシンボリックリンクと、ファイルがいくつか作成されたら終了です。

```bash
# データセットのシンボリックリンクを作成します。
# {path}にNuScenesデータセットを格納した場所を指定します。
mkdir data/nuscenes
cd data/nuscenes
ln -s {path}/maps/ maps && ln -s {path}/samples/ samples && ln -s {path}/sweeps/ sweeps && ln -s {path}/v1.0-mini/ v1.0-mini
cd ../..
# スクリプトを実行します。
# NuScenesのminiデータセット使う場合は--version v1.0-miniを引数に加えます。 
python tools/create_data.py nuscenes --root-path ./data/nuscenes --version v1.0-mini --out-dir ./data/nuscenes --extra-tag nuscenes
```

最後に以下のコマンドを実行するとデモプログラムのようにGUI画面が表示されます。

```bash
# オプション
# "show=Trueで推論実行中に可視化するフラグ。Falseで可視化を無効
# "out_dir=./data/nuscenes/show_results"で可視化データを.objファイルとして保存するディレクトリを指定
python tools/test.py configs/centerpoint/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus.py checkpoints/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus_20220810_030004-9061688e.pth --eval mAP --eval-options "show=True" "out_dir=./data/nuscenes/show_results"
```

今回はNuScenesデータセットによる推論のため、キーボード`q`キーを押すごとにフレームが切り替わっていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84781/d31d1d3c-51ae-be45-9830-0277505bfbb3.png)

`.obj`ファイルはOpen3DやMeshLabなどで可視化できます。

## 発展

推論だけでなく学習を実行したい、新しくモデルを追加したいといった場合は公式ドキュメントにやり方が書いてあります。

https://mmdetection3d.readthedocs.io/en/latest/

ただし、mmdetection3dのドキュメントだけでは不十分なためmmdetectionやmmcvのドキュメントも併せて読むことをお勧めします。

https://mmdetection.readthedocs.io/en/latest/

https://mmcv.readthedocs.io/en/latest/

### Google Colab

可視化は別で行うのであればGoogle Colabでも動かすことは可能です。
学習はColab等を使うのがよさそうです → [学習を検証した記事](https://qiita.com/np_hsgw/items/c2cdd4876d2bc72d776c)


```python
# %%
!pip3 install openmim
!mim install mmcv-full==1.7.0

# %%
!mim install mmdet

# %%
# mim経由でのインストールはかなり時間がかかる
#!mim install mmsegmentation
# 手動インストールなら早い
!git clone https://github.com/open-mmlab/mmsegmentation.git
%cd mmsegmentation
!pip install -e .
%cd ..

# %%
!git clone https://github.com/open-mmlab/mmdetection3d.git
%cd mmdetection3d
!pip install -e .

# %%
%cd mmdetection3d
%mkdir checkpoints
!wget -P ./checkpoints https://download.openmmlab.com/mmdetection3d/v1.0.0_models/centerpoint/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus_20220810_030004-9061688e.pth


# %%
%mkdir results
!python demo/pcd_demo.py demo/data/kitti/kitti_000008.bin configs/centerpoint/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus.py checkpoints/centerpoint_01voxel_second_secfpn_circlenms_4x8_cyclic_20e_nus_20220810_030004-9061688e.pth --out-dir ./results
```