Visualizing KITTI datasets using PCL Libraries

Analysis of KITTI data set

The data acquisition platform of KITTI dataset is equipped with two gray cameras, two color cameras, a Velodyne 64 line 3D lidar, four optical lenses and a GPS navigation system.

This session focuses on the lidar data part

Introduction to KITTI dataset

1.KITTI is the largest computer vision algorithm evaluation data set under automatic driving scene in the world
2.KITTI contains the real image data collected from urban, rural and expressway scenes. There are up to 15 vehicles and 30 pedestrians in each image, as well as various degrees of occlusion and truncation.
3. For 3D object detection, label is subdivided into car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram and misc.
4. The lidar is a Velodyne HDL-64E laser with a scanning frequency of 10Hz, 64 lines, 0.09 ° angular resolution, 2cm detection accuracy, 1.3 million points per second and a detection distance of 120m

KITTI basic structure

Calib: 000000~007480.txt sensor calibration data
Image_2: 000000~007480.png color camera image
Label_2: 000000~007480.txt label data set
Velodyne: 000000~007480.bin laser point cloud data
Velodyne_reduced: empty



LIDAR point cloud data is saved in floating-point binary files. Save the * * (x, y, z) * * coordinates and reflectivity r information of laser points in the lidar coordinate system, with an average of 120000 laser points per frame.

Read velodyne in KITTI dataset bin file

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

write in. pcd file

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

Open with vscode pcd file, you can intuitively see that each line is composed of x, y, z, r (reflection intensity, generally useless)

Label data analysis

First open a label and have a look

There are 15 fields in total

It is worth mentioning alpha and rotation_ Difference and connection of Y, rotation_ Both y and alpha are negative counterclockwise. They can be converted to each other.

From the schematic diagram, we can get: alpha = rotation_y - theta
**Note: * * direct conversion of data sets will cause slight loss of accuracy

Point cloud data visualization

This paper mainly uses PCLVisualizer class in PCL library to visualize point cloud data

Create a point cloud object

Read the pcd file and load the point cloud data

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

Create a window object

Define the name "3D viewer" for the title block. The type of viewer is boost::shared_ptr, can only share the pointer to ensure that the pointer is used globally in the whole program without causing memory errors

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

Set the background of the window viewer to full black

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

If you don't want a monochrome point cloud, you can render the color of the point cloud according to the depth of the z axis

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

Add point cloud to window

viewer->addPointCloud<PointXYZ>(cloud, fildColor, "sample cloud");
viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
/*Sets the size and length of the three XYZ axes, which can also be defaulted
 Viewing complex point cloud images will make users have no sense of direction. In order to maintain correct direction judgment, coordinate axes need to be displayed. The three coordinate axes X (R, red) Y(G, green) Z (B, blue) are replaced by cylinders of three different colors

Add the point cloud data to the window and define a unique string as the ID number. Use this ID number to ensure that other member methods can also represent the point cloud.
*Multiple calls to addPointCloud() can realize the superposition of multiple point clouds
*There is also the updatePointCloud() method to update the point cloud

Setting of camera parameters

This picture clearly shows the relationship between camera coordinate system and radar coordinate system
• Camera: x = right, y = down, z = forward
• Velodyne: x = forward, y = left, z = up
• GPS/IMU: x = forward, y = left, z = up

The physical distance can be obtained from the above figure
Thus, the viewing angle and direction of the camera in the point cloud can be determined

/* By setting camera parameters, the user views the point from the default angle and direction */
viewer->setCameraPosition(0.27, 0, -0.08, 1, 0, 0, 0, 0, 1);

Explain several variables in setCameraPostion
posX,posY,posZ: observation point coordinates
viewX,viewY,viewZ: viewing angle orientation
upX,upY,upZ: upward

Look at the effect

The visual label is not involved yet. It is just for comparison
It can be seen that there is no need to drag manually. After setting, the running window defaults to the same viewing angle as the camera

Keep window open

Keep the window open through the while loop, and refresh the window according to the specified time

while (!viewer->wasStopped())

3D tag data visualization

In the label of KITTI dataset, we use the 6 data of x, y, z, length, height and width in the label data to solve the 6 corner coordinates required by pcl to draw a rectangle

Define a label structure first

struct Kitti_Label
	std::string cls;// 9 classes
	//Truncation degree from 0 (truncation) - 1 (non truncation)
	float truncated;
	//Occlusion degree 0: completely visible 1: partially occluded 2: mostly occluded 3: completely occluded
	short occlusion;
	//Viewing angle range of object [- pi,pi]
	float alpha;
	//2D bounding box of the object, pixel coordinates of the upper left corner and lower right corner
	float pt1[2];
	float pt2[2];
	//Dimension of three-dimensional object, in m
	float height;
	float width;
	float length;
	//Position of 3D object (unit: m in camera coordinate system)
	float x;
	float y;
	float z;
	//The spatial direction of the three-dimensional object, the rotation angle relative to the y-axis in the camera coordinate system, range [- pi,pi]
	float rotation_y;

Read label and write member variable

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;
		istr >> sTmp[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());

coordinate transformation

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;

It should also be noted that the coordinate definition of the point cloud label is based on the bottom center

Rectangular box drawing

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);

Some blogs for reference:
There are too many references. If this article uses your information but omits the lead link, please contact the blogger. Thank you!

Keywords: AI Computer Vision Autonomous vehicles

Added by lelelow on Thu, 06 Jan 2022 07:31:32 +0200