OpenPCDet训练自定义数据
官网也提供了步骤,这里详细介绍下训练自己数据的过程以及中间遇到的一些问题。训练模型这里采用PointRCNN,具体的介绍参考:https://www.cnblogs.com/xiaxuexiaoab/p/18033887
一、准备数据集
数据集这一块我们需要准备好原始点云数据、物体目标标注文件、以及训练和验证对应的索引号,存放至OpenPCD/data/目录,其存放格式如下:
data
|---ImageSets
| |---train.txt // 存放索引号
| |---val.txt
|---labels
| |---idx.txt //第idx的标签
|---points
| |---idx.npy // 以npy形式存放点云数据
Points
相比于KITTI数据集,我们自己的数据通常只有点云坐标,也就是X,Y,Z信息,数据的坐标满足如下右手坐标系
labels
标签文件形式为c_x, c_y, c_z, dx, dy, dz, $\theta$,category_name
其中(c_x, c_y, c_z表示框的中心点, dx, dy, dz通常表示长宽高,表示长轴与x轴夹角,以弧度制表示,逆时针为正, category_name表示物体类别)。
如:
# format: [x y z dx dy dz heading_angle category_name]
1.50 1.46 0.10 5.12 1.85 4.13 1.56 Vehicle
5.54 0.57 0.41 1.08 0.74 1.95 1.57 Pedestrian
- 偏转角
除了得到目标框的中心点和大小,还需要得到训练数据(标注工具可采用SUSTechPOINTS,SSE),我们还需要确定目标的偏转角度,角度表示X轴正方向与物体方向的夹角,以弧度制表示,逆时针为正。如果物体没有明确的方向,可以采用长轴的一侧作为方向。
ImageSets
这个目录下主要存放训练和验证集的索引号,如00000, 00001等。
具体的可以参考博客给出的示例数据Tree
也可以通过百度云链接: https://pan.baidu.com/s/1FufaSbXb7z77k0PZm5h7hQ 提取码: tree
二、修改数据配置
依据数据集类别修改OpenPCD/pcdet/datasets/custom/custom_dataset.py
,将里面类别进行修改,可以进行验证
if __name__ == '__main__':
import sys
if sys.argv.__len__() > 1 and sys.argv[1] == 'create_custom_infos':
import yaml
from pathlib import Path
from easydict import EasyDict
dataset_cfg = EasyDict(yaml.safe_load(open(sys.argv[2])))
ROOT_DIR = (Path(__file__).resolve().parent / '../../../').resolve()
create_custom_infos(
dataset_cfg=dataset_cfg,
class_names=['tree'],
data_path=ROOT_DIR / 'data' / 'tree_data',
save_path=ROOT_DIR / 'data' / 'tree_data',
)
依据数据集修改OpenPCD/tools/cfgs/dataset_configs/custom_dataset.yaml
。
DATA_PATH: '../data/tree_data'
POINT_CLOUD_RANGE: [0, -10.24, -1, 10.24, 10.24, 3]
# 这个地方只会在eval阶段会用到,所以如果自己不需要eval的话可以不加
MAP_CLASS_TO_KITTI: {
'Tree': 'tree'
}
# 需要与自己的点云数据格式对应,一般不需要改
POINT_FEATURE_ENCODING: {
encoding_type: absolute_coordinates_encoding,
used_feature_list: ['x', 'y', 'z', 'intensity'],
src_feature_list: ['x', 'y', 'z', 'intensity'],
}
DATA_AUGMENTOR:
DISABLE_AUG_LIST: ['placeholder']
AUG_CONFIG_LIST:
- NAME: gt_sampling
USE_ROAD_PLANE: False
DB_INFO_PATH:
- custom_dbinfos_train.pkl
PREPARE: {
# 需要改成自己的数据集类别
filter_by_min_points: ['Tree:5'],
# filter_by_difficulty: [-1], # 这个地方如果不注释的话训练可能会报错,可以自己尝试一下
}
# 需要改成自己的数据集类别
SAMPLE_GROUPS: [Tree:15']
NUM_POINT_FEATURES: 4
DATABASE_WITH_FAKELIDAR: False
REMOVE_EXTRA_WIDTH: [0.0, 0.0, 0.0]
LIMIT_WHOLE_SCENE: True
验证:
运行以下代码
python -m pcdet.datasets.custom.custom_dataset create_custom_infos ../../../tools/cfgs/dataset_configs/custom_dataset.yaml
成功后数据目录下会生成custom_infos_val.pkl
, custom_infos_train.pkl
, custom_dbinfos_train.pkl
。
三、修改网络配置
在tools/cfgs/目录下选择对应模型的配置文件,如OpenPCD/tools/cfgs/kitti_models/pointrcnn.yaml
或 pv_rcnn.yaml
# 要改成自己的类别
CLASS_NAMES: ['Tree']
DATA_CONFIG:
_BASE_CONFIG_: cfgs/dataset_configs/custom_dataset.yaml
DATA_PROCESSOR:
# - NAME: mask_points_and_boxes_outside_range
# REMOVE_OUTSIDE_BOXES: True
- NAME: sample_points
NUM_POINTS: {
'train': 7000,
'test': 7000
}
- NAME: shuffle_points
SHUFFLE_ENABLED: {
'train': True,
'test': False
}
对于基于体素的网络来说,体素大小与点云范围有比例关系,需要设置成符号条件的数值才行!!!点云范围和VOXEL_SIZE要有一定关系,Z轴/VOXEL_SIZE=40 X、Y轴/VOXEL_SIZE是16的倍数即可。
四、训练及验证
训练
以PointRCNN为例,修改pointrcnn.yaml配置后,执行以下命令
python train.py --cfg_file ./cfgs/kitti_models/pointrcnn.yaml
测试
- 测试训练后的模型
python test.py --cfg_file ${CONFIG_FILE} --batch_size ${BATCH_SIZE} --ckpt ${CKPT}
- 测试所有训练的模型,并在Tensorboard上显示, 则添加--eval_all
python test.py --cfg_file ${CONFIG_FILE} --batch_size ${BATCH_SIZE} --eval_all
效果展示
我这里只跑了60次,框还是蛮准的,只是角度差了点。
- 003
### label
0.6606626881677105 8.660001144758255 0.7745344942911313 1.0835368467351851 0.9695020007915394 3.347787319401136 1.7540558982543013 Tree
6.659072735886389 7.514472529730539 1.2639978186871488 1.199480951252865 0.9679843423539747 2.9697279494139175 -0.8115781021773634 Tree
5.275455441527495 -6.202045702857098 0.9603300130836927 0.6454945360426863 0.572657854807775 2.6103752114417125 0.1308996938995747 Tree
### predict
6.5928 7.5321 1.4458 0.9020 0.9444 3.2552 -2.7597 0
5.2310 -6.1709 1.0242 0.6488 0.6948 2.8370 -2.8066 0
0.7735 8.5778 0.7330 0.8715 0.9003 3.1873 -2.3646 0
- 039
### label
9.656114943323836 -6.072699760871513 1.6887055885943718 0.9799560579727205 0.8213381447187522 2.9618450129808847 2.38237442897226 Tree
3.5277369578356867 -5.819254215657011 0.7713895010955505 0.5623637969685309 0.6515302113635831 2.2568508720412592 2.015855286053451 Tree
8.864816477941408 8.055170541354029 1.2612759645145013 0.7098272195551462 0.908273873961106 2.918564880815968 1.4398966328953218 Tree
2.329600500773367 8.582458537044301 0.7314550633201173 0.9060115816526095 1.0885560636920202 3.4163465986710446 -1.4922565104551522 Tree
### predict
9.6919 -6.0800 1.8377 0.6415 0.6879 2.8373 -2.9894 0
8.8507 7.9449 1.3055 0.8138 0.8480 3.0745 -2.8349 0
2.3120 8.5875 0.6982 0.9842 1.0026 3.3009 -2.3022 0
3.4150 -5.7833 0.8418 0.5108 0.5655 2.5805 -1.7507 0
五、常见问题
- ValueError: attempted relative import beyond top-level package
运行custom_dataset.py的时候出现以下错误,pycharm里面可以正常跳转,但运行会报错
from ...ops.roiaware_pool3d import roiaware_pool3d_utils
ValueError: attempted relative import beyond top-level package
解决方法
...ops.roiaware_pool3d
替换为 pcdet.ops.roiaware_pool3d
相关解释:https://stackoverflow.com/questions/30669474/beyond-top-level-package-error-in-relative-import
- Error ModuleNotFoundError: No module named 'av2'
OpenPCDet/pcdet/datasets/argo2/argo2_dataset.py", line 7, in <module>
from av2.utils.io import read_feather
ModuleNotFoundError: No module named 'av2'
解决方法
注释掉OpenPCD/pcdet/datasets/__init__.py
的15行和27行
# from .argo2.argo2_dataset import Argo2Dataset
from .custom.custom_dataset import CustomDataset
__all__ = {
'DatasetTemplate': DatasetTemplate,
'KittiDataset': KittiDataset,
'NuScenesDataset': NuScenesDataset,
'WaymoDataset': WaymoDataset,
'PandasetDataset': PandasetDataset,
'LyftDataset': LyftDataset,
'ONCEDataset': ONCEDataset,
'CustomDataset': CustomDataset,
# 'Argo2Dataset': Argo2Dataset
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2023-05-15 深度学习---2D视觉领域分类