nuscenes2kitti-Nuscenes数据集转KITTI数据集格式目录结构
- 更多bev算法部署参考
- nuscenes2kitti-github地址
- nus的雷达系(右手系,x右,y向, z上), 相机系(图像平面上看 ,x右, y下,z前)
- 这里强调一下常规雷达系(右手拿出来比划,x前, y左, z上)
- 重要事情说3遍:常规雷达系 右手比划一下,右手比划一下,右手比划一下!!!
1 环境配置
可以直接看github-readme , 代码直接看nus2common.py带注释, 有问题github留言,本帖后面内容可不看。
基本依赖:ros1环境和一个能运行mmdet3d工程的python
# 1 创建工作空间
mkdir -p nus2kitti_ws/src && cd nus2kitti_ws/src
# 2 拉取源码
git clone https://github.com/linClubs/nuscenes2kitti.git
# 3 记得切一个能运行BEVFusion,fastbev,bevdet,mmdetetion3d的python虚拟环境运行该工程
# 4 报错需要什么库就编译什么库
# 4 编译
cd nus2kitti_ws && catkin_make
2 坐标系介绍
- nus中的雷达系为右手系,x向右,y向前,z向上
- 原始token中3D的标注框是基于world系的。
- 使用
nusc.get_sample_data
该api
返回的box
是在当前传感器下
from nuscenes.nuscenes import NuScenes
nusc = NuScenes(version='v1.0-mini', dataroot=dataroot, verbose=True) # 读取数据集
# 使用的lidar_token, 所以3Dbox是lidar系下
lidar_path, boxes, _ = nusc.get_sample_data(lidar_token)
2.1 标准的lidar系
-
常规的lidar坐标系,满足右手系,当x向前,y向左,z向上,与nus差了yaw=90°
-
opendet3d和mmdetection3d框架都是统一坐标系,使用常规的lidar坐标系
-
3D标注容易搞混,但mmdetection3d统一了。使用7维的量表示
- 都以box自身中心为原点, 运动方向为x方向的右手系,确定x,y,z,dx,dy,dz
- yaw角box运动方向与常规lidar系(x向前)的y轴负方向的夹角(就是水平的夹角), 绕z的逆时针转为正
- 如果box运动方向为y轴负方向, 即yaw=0°,box运动方向为x轴,即yaw=90°
- 这里不考虑pitch和roll角, 通常深度学习使用的数据集都只使用了yaw角
x, y, z, dx, dy, dz, yaw
- 这样定义的好处:
- 用户不用再考虑到底wlh还是lwh顺序, yaw角的正负
- 用户不用再考虑中心点是3d框的几何中心还是底面中心
- nus中标注,默认的box的wlh对应是dy,dx,dz, 注意dy,dx,dz的顺序
- kitti中标注:
转向角 (yaw) 的参考方向为 y 轴正方向, 即box运动方向为y轴时,yaw=0°
尺寸为(w, l, h)对应 dy,dx,dz
2.2 nus标注数据变换到统一坐标系下
- 统一坐标系默认指常规的lidar系(x向右,y向前,z向上)
- nus中的box的值需要绕z轴旋转90°即可。
- 由于box的dx, dy, dz是以自身为参考系,刚体变换过程中值保持不变,
- 只需要将x, y, z, yaw旋转90°即可
3 nus转kitti保存格式
- kitti的目录结构比较人看比较直观, 所以可以使用kitti的目录结构制作数据集
3.1 nus坐标系转常规的lidar系nus2common.py
-
点云信息:
nus
的坐标系(右手x
右) -> 常规的坐标lidar
系x
向前 -
标注信息:
nus
是相对于world系
-> 转换到正常的lidar
系 , T ( − 90 ° ) ∗ T _ l i d a r _ w o r l d T_{(-90°)} * T_{\_lidar\_world} T(−90°)∗T_lidar_world -
nus2common.py
中137
行左右,坐标系旋转-90
° -
lidar
数据和标注框信息都是基于正常的lidar系(右手系x向前,y向左,z向上), 标注:x y z dx dy dz yaw
-
传感器标定参数注意nus-lidar系已变成常规的lidar系, 主要是外参 T _ c a m _ l i d a r T_{\_cam\_lidar} T_cam_lidar
# 1 启动发布nus到lidar的变换 ros发布正常lidar系的点云 前视图 box
# 主要配置nus2common.py中dataroot与saveroot路径, 建议使用下面的roslaunch
rosrun nus_pkg nus2common.py
# 2 使用roslaunch启动
# 主要配置nus2common.launch中dataroot与saveroot路径
roslaunch nus_pkg nus2common.launch
rviz
显示如下:
图中可以看到雷达的坐标系x前y左z上,图像右边正前方的车的3Dbox的yaw角也是朝前的(x方向)
- 最终生成的数据目录如下:
mmdetetion3d
├── data
│ ├── common
│ │ ├── calib
│ │ │ ├── 000000.txt
│ │ │ ├── 000001.txt
│ │ │ ├── ...
│ │ ├── images
│ │ │ ├── CAM_FRONT_LEFT
│ │ │ │ ├── 000000.png
│ │ │ │ ├── 000001.png
│ │ │ │ ├── ...
│ │ │ ├── CAM_FRONT
│ │ │ ├── CAM_FRONT_RIGHT
│ │ │ ├── ...
│ │ ├── labels
│ │ │ ├── 000000.txt
│ │ │ ├── 000001.txt
│ │ │ ├── ...
│ │ ├── points
│ │ │ ├── 000000.bin
│ │ │ ├── 000001.bin
│ │ │ ├── ...
3.2 常规lidar系转kitti的相机系
- 代码启动
# 1 修改common2kitti.py文件中dataroot与saveroot两个参数即可
# dataroot为常规的lidar系格式的数据集可由7.1小节得到,saveroot生成kitti的格式的保存路径
# 2 进入代码目录
cd scripts
# 3 运行common2kitti.py
python common2kitti.py
# 生成的kitti格式保存在saveroot路径下
- 常规lidar系 -> kitti格式: 注意外参 T _ l i d a r 2 c a m T_{\_lidar2cam} T_lidar2cam, 标注信息xyz和yaw的变化
- kitti的标注信息是相机系
- kitti是以底面中心为box原点
- kitti的dim是hwl顺序
- kitti格式是15维度:
type, # name id: 0
truncated, occluded, alpha, # 截断 遮挡 观测角度 1 0 0.0 id: 1 2 3
bbox_2d(lt-rd,pixel), # [0.00, 0.00, 50.00, 50.00] 全设为0,处理时默认无效,id: 4567
dimensions-3d(m), # hwl id: 8 9 10
location_3d, # xyz id: 11 12 13 # 注意kitti是以底面中心为box原点
rotation_y_3d, # yaw id: 14
score # 自己数据集无score, 可不写
- lidar系没变,所有传感器标定参数不变
- kiiti的标注是以相机坐标系为基准,所以需要将box转到相机系 T_cam_lidar * Box
- 相机的y轴正向朝下, loc的y分量 + dz/2
# 1 R_cam_lidar 90 -90 0
Eigen::Matrix3d R_cam_lidar;
R_cam_lidar << 0, -1, 0, 0, 0, -1, 1, 0, 0;
locs_cam = T_cam_lidar * locs_lidar
kitti["location"] = [locs_cam[0], locs_cam[1] + float(dz)/2 , locs_cam[2]
- 旋转y轴正向朝下, 绕y轴转:
yaw = -yaw
- kitti[“dimensions”]注意顺序即可
kitti["dimensions"] = [dz, dy, dx]
4 自制kitti格式
一般3D标注都是以常规雷达系,标点云数据上的框,
- 使用mmopenlab框架并不需要一定做成严格的kitti格式,只是kitti的保存数据集人看比较dict格式直观
- 如果是只是3D任务可以直接使用以常规lidar系下为基准的标注信息
- 如果遇到问题或者代码有误,请留言评论区或者github-issue区
- 更多bev算法部署参考