ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用PCL库将KITTI数据集可视化

2022-01-06 13:33:01  阅读:461  来源: 互联网

标签:tar viewer float 点云 num 可视化 PCL test KITTI


PCL点云可视化

KITTI数据集浅析

KITTI数据集的数据采集平台装配有2个灰度摄像机,2个彩色摄像机,一个Velodyne 64线3D激光雷达,4个光学镜头,以及1个GPS导航系统。

本次重点讨论激光雷达数据部分

KITTI数据集简介

1.KITTI是目前国际上最大的自动驾驶场景下的计算机视觉算法评测数据集
2.KITTI包含市区、乡村和高速公路等场景采集的真实图像数据,每张图像中最多达15辆车和30个行人,还有各种程度的遮挡与截断
3.对于3D物体检测,label细分为car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram以及misc组成。
4. 激光雷达为1台Velodyne HDL-64E激光,扫描频率10Hz,64线,0.09°角度分辨率,2cm探测精度,每秒130万点数,探测距离120m

KITTI基本结构

KITTI数据集的文件目录
Calib: 000000~007480.txt 传感器标定数据
Image_2: 000000~007480.png 彩色相机图像
Label_2: 000000~007480.txt 标注数据集合
Velodyne: 000000~007480.bin 激光点云数据
Velodyne_reduced: 空

Calib


Velodyne

激光雷达点云数据采用浮点数二进制文件保存。保存激光雷达坐标系下,激光点**( x , y , z )** 坐标和反射率r信息,每一帧平均12万个激光点。

读取KITTI数据集中velodyne的.bin文件

pcl::PointCloud<PointXYZI>::Ptr points (new pcl::PointCloud<PointXYZI>);
for (int i=0; input.good() && !input.eof(); i++)
{
	PointXYZI point;
	input.read((char *) &point.x, 3*sizeof(float));
	input.read((char *) &point.intensity, sizeof(float));
	points->push_back(point);
}
input.close();

写入.pcd文件

pcl::PCDWriter writer;
writer.write<PointXYZI> (outfile, *points, false);
PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);

用vscode打开.pcd文件,可以直观的看到每行都由x,y,z,r(反射强度,一般没用)组成
在这里插入图片描述

标签数据解析

先打开一个label看一下

在这里插入图片描述
一共15个字段
在这里插入图片描述
值得提一下的是alpha和rotation_y的区别和联系,rotation_y和alpha都是以逆时针方向为负。它们之间可以互相转换。
在这里插入图片描述
从示意图可以分析得到:alpha = rotation_y - theta
**注意:**直接对数据集转换,会有轻微的精度损失

点云数据可视化

本文主要使用PCL库中的PCLVisualizer类对点云数据进行可视化操作

创建点云对象

读取pcd文件,载入点云数据

PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
if (io::loadPCDFile("test.pcd", *cloud) == -1)
	return -1;

创建视窗对象

给标题栏定义名称“3D viewer”。viewer的类型为boost::shared_ptr,只能共享指针,保证该指针在整个程序中全局使用,不引起内存错误

boost::shared_ptr<visualization::PCLVisualizer> viewer(new visualization::PCLVisualizer("3D viewer"));

设置窗口viewer的背景为全黑色

viewer->setBackgroundColor(0, 0, 0);

如果不想要单色的点云,可以按z轴方向深度渲染一下点云的色彩

pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");

添加点云到视窗

viewer->addPointCloud<PointXYZ>(cloud, fildColor, "sample cloud");
viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
/*设置XYZ三个坐标轴的大小和长度,该值也可以缺省
查看复杂的点云图像会让用户没有方向感,为了让用户保持正确的方向判断,需要显示坐标轴。三个坐标轴X(R,红色)Y(G,绿色)Z(B,蓝色)分别用三种不同颜色的圆柱体代替
*/

将点云数据添加到视窗中,并为其定义一个唯一的字符串作为ID号,利用此ID号保证其他成员方法也能表示该点云。
*多次调用addPointCloud()可以实现多个点云的叠加
*还有updatePointCloud()方法实现点云的更新

相机参数的设置

在这里插入图片描述
这张图清楚地展示了相机坐标系和雷达坐标系的关系
• Camera: x = right, y = down, z = forward
• Velodyne: x = forward, y = left, z = up
• GPS/IMU: x = forward, y = left, z = up
在这里插入图片描述
而物理距离可以由上图获得
由此可以确定点云中相机的视角和方向

viewer->addCoordinateSystem(1.0);
/* 通过设置相机参数是用户从默认的角度和方向观察点 */
viewer->initCameraParameters();
viewer->setCameraPosition(0.27, 0, -0.08, 1, 0, 0, 0, 0, 1);

解释一下setCameraPostion中的几个变量
posX,posY,posZ: 观察点坐标
viewX,viewY,viewZ: 视角朝向
upX,upY,upZ: 向上方向

看下效果
在这里插入图片描述

在这里插入图片描述

还没有涉及可视化label,此处只是为了方便对照
可以看到,不用手动拖拽,设置好后,运行窗口默认和相机同一视角

保持窗口打开

通过while循环保持窗口一直处于打开状态,并且按照规定时间刷新窗口

while (!viewer->wasStopped())
{
	viewer->spinOnce(100);
	boost::this_thread::sleep(boost::posix_time::microseconds(1000));
}

3D标签数据可视化

在KITTI数据集的标签里,我们用到它标签数据里的x,y,z,length,height,width6个数据,来求解pcl绘制矩形所需要的6个角点坐标

先定义一个标签结构体

struct Kitti_Label
{
	//类别
	std::string cls;// 9 classes
	//截断程度 from 0(截断)-1(非截断)
	float truncated;
	//遮挡程度 0 完全可见 1 小部分遮挡 2 大部分遮挡 3 完全遮挡
	short occlusion;
	//物体的观察角度 范围[-pi,pi]
	float alpha;
	//物体的2维边界框,左上角和右下角的像素坐标
	float pt1[2];
	float pt2[2];
	//三维物体的尺寸,单位m
	float height;
	float width;
	float length;
	//三维物体的位置(相机坐标系下,单位m)
	float x;
	float y;
	float z;
	//三维物体的空间方向,在相机坐标系下,相对于y轴的旋转角,范围[-pi,pi]
	float rotation_y;
}

读取label,写入成员变量

ifstream txtfile("test.txt");
Kitti_Label test[100];
string s;

int num_tar = 0;
while (getline( txtfile, s))
{
	string sTmp[15];
	istringstream istr(s);
	int i = 0;
	while(!istr.eof())
	{
		istr >> sTmp[i];
		i++;
	}
	test[num_tar].cls = sTmp[0]
	test[num_tar].x = atof(sTmp[11].c_str());
	test[num_tar].y = atof(sTmp[12].c_str());
	test[num_tar].z = atof(sTmp[13].c_str());
	test[num_tar].height = atof(sTmp[8].c_str());
	test[num_tar].width = atof(sTmp[9].c_str());
	test[num_tar].length = atof(sTmp[10].c_str());
	
}

坐标转换

在这里插入图片描述

float x_min = test[num_tar].z - test[num_tar].length/2;
float y_min = -test[num_tar].x - test[num_tar].length/2;
float z_min = -test[num_tar].y;
float x_max = test[num_tar].z + test[num_tar].length/2;
float y_max = -test[num_tar].x + test[num_tar].length/2;
float z_max = -test[num_tar].y + test[num_tar].length;

还有一点要注意的,点云标签的坐标定义是以底面中心为准

矩形框绘制

viewer->addCube (x_min, x_max, y_min, y_max, z_min, z_max, 255, 0, 0, name, 0);
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION,pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, name);

参考的一些博客:

https://blog.csdn.net/zjguilai/article/details/90168564
https://blog.csdn.net/qq_37534947/article/details/106628308
参考的资料不胜枚举,本文如有使用您的资料,却遗漏引出链接,请与博主联系,谢谢!

标签:tar,viewer,float,点云,num,可视化,PCL,test,KITTI
来源: https://blog.csdn.net/sumang0211/article/details/122338442

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有