README.md 11.8 KB
Newer Older
K
Kaipeng Deng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
# PointRCNN 3D目标检测模型

---
## 内容

- [简介](#简介)
- [快速开始](#快速开始)
- [参考文献](#参考文献)
- [版本更新](#版本更新)

## 简介

[PointRCNN](https://arxiv.org/abs/1812.04244) 是 Shaoshuai Shi, Xiaogang Wang, Hongsheng Li. 等人提出的,是第一个仅使用原始点云的2-stage(两阶段)3D目标检测器,第一阶段将 Pointnet++ with MSG(Multi-scale Grouping)作为backbone,直接将原始点云数据分割为前景点和背景点,并利用前景点生成bounding box。第二阶段在标准坐标系中对生成对bounding box进一步筛选和优化。该模型还提出了基于bin的方式,把回归问题转化为分类问题,验证了在三维边界框回归中的有效性。PointRCNN在KITTI数据集上进行评估,论文发布时在KITTI 3D目标检测排行榜上获得了最佳性能。

网络结构如下所示:

<p align="center">
<img src="images/teaser.png" height=300 width=800 hspace='10'/> <br />
用于点云的目标检测器 PointNet++
</p>

**注意:** PointRCNN 模型构建依赖于自定义的 C++ 算子,目前仅支持GPU设备在Linux/Unix系统上进行编译,本模型**不能运行在Windows系统或CPU设备上**


## 快速开始

### 安装

**安装 [PaddlePaddle](https://github.com/PaddlePaddle/Paddle):**

在当前目录下运行样例代码需要 PaddelPaddle Fluid [develop每日版本](https://www.paddlepaddle.org.cn/install/doc/tables#多版本whl包列表-dev-11)或使用PaddlePaddle [develop分支](https://github.com/PaddlePaddle/Paddle/tree/develop)源码编译安装. 

为了使自定义算子与paddle版本兼容,建议您**优先使用源码编译paddle**,源码编译方式请参考[编译安装](https://www.paddlepaddle.org.cn/install/doc/source/ubuntu)

**安装PointRCNN:**

1. 下载[PaddlePaddle/models](https://github.com/PaddlePaddle/models)模型库

通过如下命令下载Paddle models模型库:

```
git clone https://github.com/PaddlePaddle/models
```

2.`PaddleCV/Paddle3D/PointRCNN`目录下下载[pybind11](https://github.com/pybind/pybind11)

`pts_utils`依赖`pybind11`编译,须在`PaddleCV/Paddle3D/PointRCNN`目录下下载`pybind11`子库,可使用如下命令下载:

```
cd PaddleCV/Paddle3D/PointRCNN
git clone https://github.com/pybind/pybind11
```

54
3. 安装python依赖库
K
Kaipeng Deng 已提交
55 56 57 58 59 60 61 62 63 64

使用如下命令安装python依赖库:

```
pip install -r requirement.txt
```

**注意:** KITTI mAP评估工具只能在python 3.6及以上版本中使用,且python3环境中需要安装`scikit-image`,`Numba`,`fire`等子库。
`requirement.txt`中的`scikit-image`,`Numba`,`fire`即为KITTI mAP评估工具所需依赖库。

65 66 67 68 69 70 71
4. 编译安装`pts_utils`, `kitti_utils`, `roipool3d_utils`, `iou_utils` 等模块

使用如下命令编译安装`pts_utils`, `kitti_utils`, `roipool3d_utils`, `iou_utils` 等模块:
```
sh build_and_install.sh
```

K
Kaipeng Deng 已提交
72 73 74 75 76 77 78 79 80 81 82 83
### 编译自定义OP

请确认Paddle版本为PaddelPaddle Fluid develop每日版本或基于Paddle develop分支源码编译安装,**推荐使用源码编译安装的方式**

自定义OP编译方式如下:

    进入 `ext_op/src` 目录,执行编译脚本
    ```
    cd ext_op/src
    sh make.sh
    ```

84
    成功编译后,`ext_op/src` 目录下将会生成 `pointnet_lib.so` 
K
Kaipeng Deng 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

    执行下列操作,确保自定义算子编译正确:

    ```
    # 设置动态库的路径到 LD_LIBRARY_PATH 中
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`python -c 'import paddle; print(paddle.sysconfig.get_lib())'`

    # 回到 ext_op 目录,添加 PYTHONPATH
    cd ..
    export PYTHONPATH=$PYTHONPATH:`pwd`

    # 运行单测 
    python tests/test_farthest_point_sampling_op.py
    python tests/test_gather_point_op.py
    python tests/test_group_points_op.py
    python tests/test_query_ball_op.py
    python tests/test_three_interp_op.py
    python tests/test_three_nn_op.py
    ```
    单测运行成功会输出提示信息,如下所示:

    ```
    .
    ----------------------------------------------------------------------
    Ran 1 test in 13.205s

    OK
    ```

**说明:** 自定义OP编译与[PointNet++](../PointNet++)下一致,更多关于自定义OP的编译说明,请参考[自定义OP编译](../PointNet++/ext_op/README.md)

### 数据准备

**KITTI 3D object detection 数据集:**

PointRCNN使用数据集[KITTI 3D object detection](http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d) 
上进行训练。

可通过如下方式下载数据集:

```
cd data/KITTI/object
sh download.sh
```

此处的images只用做可视化,训练过程中使用[road planes](https://drive.google.com/file/d/1d5mq0RXRnvHPVeKx6Q612z0YRO1t2wAp/view?usp=sharing)数据来做训练时的数据增强,
请下载并解压至`./data/KITTI/object/training`目录下。

数据目录结构如下所示:

```
PointRCNN
├── data
│   ├── KITTI
│   │   ├── ImageSets
│   │   ├── object
│   │   │   ├──training
│   │   │   │  ├──calib & velodyne & label_2 & image_2 & planes
│   │   │   ├──testing
│   │   │   │  ├──calib & velodyne & image_2

```


### 训练

**PointRCNN模型:**

可通过如下方式启动 PointRCNN模型的训练:

1. 指定单卡训练并设置动态库路径

```
# 指定单卡GPU训练
export CUDA_VISIBLE_DEVICES=0

# 设置动态库的路径到 LD_LIBRARY_PATH 中
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`python -c 'import paddle; print(paddle.sysconfig.get_lib())'`
```

2. 生成Groud Truth采样数据,命令如下:

```
python tools/generate_gt_database.py --class_name 'Car' --split train
```

3. 训练 RPN 模型

```
python train.py --cfg=./cfgs/default.yml \
                --train_mode=rpn \
                --batch_size=16 \
                --epoch=200 \
                --save_dir=checkpoints
```

RPN训练checkpoints默认保存在`checkpoints/rpn`目录,也可以通过`--save_dir`来指定。

4. 生成增强离线场景数据并保存RPN模型的输出特征和ROI,用于离线训练 RCNN 模型

生成增强的离线场景数据命令如下:

```
python tools/generate_aug_scene.py --class_name 'Car' --split train --aug_times 4
```

保存RPN模型对离线增强数据的输出特征和ROI,可以通过参数`--ckpt_dir`来指定RPN训练最终权重保存路径,RPN权重默认保存在`checkpoints/rpn`目录。
保存输出特征和ROI时须指定`TEST.SPLIT``train_aug`,指定`TEST.RPN_POST_NMS_TOP_N``300`, `TEST.RPN_NMS_THRESH``0.85`
通过`--output_dir`指定保存输出特征和ROI的路径,默认保存到`./output`目录。

```
python eval.py --cfg=cfgs/default.yml  \
               --eval_mode=rpn \
               --ckpt_dir=./checkpoints/rpn/199 \
               --save_rpn_feature \
               --output_dir=output \
               --set TEST.SPLIT train_aug TEST.RPN_POST_NMS_TOP_N 300 TEST.RPN_NMS_THRESH 0.85
```

`--output_dir`下保存的数据目录结构如下:

```
output
├── detections 
│   ├── data          # 保存ROI数据
│   │   ├── 000000.txt
│   │   ├── 000003.txt
│   │   ├── ...
├── features          # 保存输出特征
│   ├── 000000_intensity.npy
│   ├── 000000.npy
│   ├── 000000_rawscore.npy
│   ├── 000000_seg.npy
│   ├── 000000_xyz.npy
│   ├── ...
├── seg_result        # 保存语义分割结果
│   ├── 000000.npy
│   ├── 000003.npy
│   ├── ...
```

5. 离线训练RCNN,并且通过参数`--rcnn_training_roi_dir` and `--rcnn_training_feature_dir` 来指定 RPN 模型保存的输出特征和ROI路径。

```
python train.py --cfg=./cfgs/default.yml \
                --train_mode=rcnn_offline \
                --batch_size=4 \
                --epoch=30 \
                --save_dir=checkpoints \
                --rcnn_training_roi_dir=output/detections/data \
K
Kaipeng Deng 已提交
235 236
                --rcnn_training_feature_dir=output/features \
                --set TRAIN.SPLIT train_aug
K
Kaipeng Deng 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
```

RCNN模型训练权重默认保存在`checkpoints/rcnn`目录下,可通过`--save_dir`参数指定。

**注意**: 最好的模型是通过保存RPN模型输出特征和ROI并离线数据增强的方式训练RCNN模型得出的,目前默认仅支持这种方式。


### 模型评估

**PointRCNN模型:**

可通过如下方式启动 PointRCNN 模型的评估:

1. 指定单卡训练并设置动态库路径

```
# 指定单卡GPU训练
export CUDA_VISIBLE_DEVICES=0

# 设置动态库的路径到 LD_LIBRARY_PATH 中
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`python -c 'import paddle; print(paddle.sysconfig.get_lib())'`

```

2. 保存RPN模型对评估数据的输出特征和ROI

保存RPN模型对评估数据的输出特征和ROI命令如下,可以通过参数`--ckpt_dir`来指定RPN训练最终权重保存路径,RPN权重默认保存在`checkpoints/rpn`目录。
通过`--output_dir`指定保存输出特征和ROI的路径,默认保存到`./output`目录。

```
python eval.py --cfg=cfgs/default.yml \
               --eval_mode=rpn \
               --ckpt_dir=./checkpoints/rpn/199 \
               --save_rpn_feature \
               --output_dir=output/val
```

保存RPN模型对评估数据的输出特征和ROI保存的目录结构与上述保存离线增强数据保存目录结构一致。

3. 评估离线RCNN模型

评估离线RCNN模型命令如下:

```
python eval.py --cfg=cfgs/default.yml \
               --eval_mode=rcnn_offline \
               --ckpt_dir=./checkpoints/rcnn_offline/29 \
               --rcnn_eval_roi_dir=output/val/detections/data \
               --rcnn_eval_feature_dir=output/val/features \
               --save_result
```

最终目标检测结果文件保存在`./result_dir`目录下`final_result`文件夹下,同时可通过`--save_result`开启保存`roi_output``refine_output`结果文件。
`result_dir`目录结构如下:

```
result_dir
├── final_result
│   ├── data          # 最终检测结果
│   │   ├── 000001.txt
│   │   ├── 000002.txt
│   │   ├── ...
├── roi_output
│   ├── data          # RCNN模型输出检测ROI结果
│   │   ├── 000001.txt
│   │   ├── 000002.txt
│   │   ├── ...
├── refine_output
│   ├── data          # 解码后的检测结果
│   │   ├── 000001.txt
│   │   ├── 000002.txt
│   │   ├── ...
```

4. 使用KITTI mAP工具获得评估结果

若在评估过程中使用的python版本为3.6及以上版本,则程序会自动运行KITTI mAP评估,若使用python版本低于3.6,
由于KITTI mAP仅支持python 3.6及以上版本,须使用对应python版本通过如下命令进行评估:

```
317
python3 tools/kitti_eval.py
K
Kaipeng Deng 已提交
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
```

使用训练最终权重[RPN模型](https://paddlemodels.bj.bcebos.com/Paddle3D/pointrcnn_rpn.tar)[RCNN模型](https://paddlemodels.bj.bcebos.com/Paddle3D/pointrcnn_rcnn_offline.tar)评估结果如下所示:

|  Car AP@ | 0.70(easy) | 0.70(moderate) | 0.70(hard) |
| :------- | :--------: | :------------: | :--------: |
| bbox AP: |   90.20    |     88.85      |   88.59    |
| bev  AP: |   89.50    |     86.97      |   85.58    |
| 3d   AP: |   86.66    |     76.65      |   75.90    |
| aos  AP: |   90.10    |     88.64      |   88.26    |


## 参考文献

- [PointRCNN: 3D Object Proposal Generation and Detection From Point Cloud](https://arxiv.org/abs/1812.04244), Shaoshuai Shi, Xiaogang Wang, Hongsheng Li.
- [PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space](https://arxiv.org/abs/1706.02413), Charles R. Qi, Li Yi, Hao Su, Leonidas J. Guibas.
- [PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation](https://www.semanticscholar.org/paper/PointNet%3A-Deep-Learning-on-Point-Sets-for-3D-and-Qi-Su/d997beefc0922d97202789d2ac307c55c2c52fba), Charles Ruizhongtai Qi, Hao Su, Kaichun Mo, Leonidas J. Guibas.

## 版本更新

- 11/2019, 新增 PointRCNN模型。