前言
主要记录PCL库使用过程中的一些内容,方便自己回看。
一、pcd 格式数据读取与写入
读取:
pcl::PointCloud<pcl::PointXYZ>::Ptr loadcloud(
new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile(lidar_filename_path, *loadcloud)) {
cerr << "ERROR: Cannot open file " << lidar_filename_path
<< "! Aborting..." << endl;
return false;
}
写入:
pcl::io::savePCDFileASCII<pcl::PointXYZI> ( save_path, *Cloud);
二、自定义点云格式
按照官方教程的说明可作如下定义:
#include <pcl/point_types.h>
struct PointCloudXYZRD{
PCL_ADD_POINT4D;
float range;
int ring;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
}EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT(PointCloudXYZRD,
(float,x,x)
(float,y,y)
(float,z,z)
(int,ring,ring)
(float,range,range)
)
PointCloudXYZRD 就是定义的新点云格式, PCL_ADD_POINT4D是原有的点云基本x,y,z属性,这里再给格式添加range 以及 ring。此外要想cloudviewer能够正常显示你定义的点云格式,还需要添加头文件:
#include <pcl/visualization/impl/point_cloud_geometry_handlers.hpp>
三、自定义点云bin格式读取与存储
保存bin
bin格式为二进制文件,能够一定程度上减少点云存储数据量。
保存时想要将所有点云属性进行保存,可进行如下定义,使用的就是c++中的fstream的保存二进制文件方式即可:
std::ofstream out(lidar_file_name, std::ios::binary);//二进制
int nume = cloud->points.size();
float *data = new float[nume*7]; //存储数据大小
int se = 0;
for(int i = 0; i < nume; ++i) {
data[se] = cloud->points[i].x;
data[se+1] = cloud->points[i].y;
data[se+2] = cloud->points[i].z;
data[se+3] = cloud->points[i].intensity;
data[se+4] = cloud->points[i].azimuth; //旋转角
data[se+5] = cloud->points[i].range; //距离
data[se+6] = cloud->points[i].ring;
se += 7;
}
out.write(reinterpret_cast<char*>(data), nume*7*sizeof(float)); //均采用float格式存储
out.close();
delete []data; //删除临时存储
读取bin
首先定义读取的数据格式:
typedef struct {
float x,y,z,intensity,azimuth,range, ring;
} point_data_t;
接着对数据进行读取
ifstream inputfile;
inputfile.open(lidar_filename_path, ios::binary);
if (!inputfile) {
cerr << "ERROR: Cannot open file " << lidar_filename_path
<< "! Aborting..." << endl;
return false;
}
inputfile.seekg(0, ios::beg);//定位到文件开头
for (int i = 0; inputfile.good() && !inputfile.eof(); i++) { //判断文件是否读取结束
point_data_t data;
inputfile.read(reinterpret_cast<char*>(&data), sizeof(data));
pcl::PointXYZI p;
p.x = data.x;
p.y = data.y;
p.z = data.z;
p.intensity = data.intensity;
p.azimuth = data.azimuth;
p.range = data.range;
p.ring = data.ring;
cloud.points.push_back(p);//数据转至pcl点云数据格式中
}