点云存储文件格式有很多格式,pcd格式是PCL官方指定的格式,为点云量身定制。其中pcd格式在PCL库具有保存具备文本和二进制两种格式进行保存。当然,PCL官方库中也支持ply文件格式的读取与介绍。
读取/保存pcd文件之一:
// Read PCD File
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ> ("../path/xx.pcd", *cloud) == -1) //* load the file
{
PCL_ERROR ("Couldn't read file test_pcd.pcd \n");
return (-1);
}
// Save PCD File
pcl::io::savePCDFile<pcl::PointXYZ> ("../save_path/xx.pcd", *cloud);
读取/保存pcd文件之二:
// Read PCD File
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read<pcl::PointXYZ>("../xx.pcd", *cloud);
// Save PCD File
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("../save_xx.pcd", *cloud);
读取/保存ply文件:
// Read PLY File.
pcl::io::loadPLYFile<pcl::PointXYZ>();
// Save PLY File.
pcl::io::savePLYFile<pcl::PointXYZ>();
// Read PLY File Other Ways.
pcl::PLYReader reader;
// Save PLY File Other Ways.
pcl::PLYWriter writer;
我们以kitti数据集为基本数据,将其bin文件转换为pcd格式文件:
bin解析代码片段:
// load point cloud file.
std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);// in_file 为点云bin文件
if (!input.good())
{
std::cerr << "Could not read file: " << in_file << std::endl;
exit(EXIT_FAILURE);
}
input.seekg(0, std::ios::beg);
pcl::PointCloud<pcl::PointXYZI>::Ptr points(new pcl::PointCloud<pcl::PointXYZI>);// 点云存储解析bin后的数据
for(int i=0; input.good() && !input.eof(); i++)
{
pcl::PointXYZI point;
input.read((char *)&point.x, 3*sizeof(float));
input.read((char *)&point.intensity, sizeof(float));
points->push_back(point);
}
input.close();
上述代码片段解析kitti中的点云bin文件,我们获取解析后的bin点云数据后,存储模式为pcd或者ply(注释的部分)格式,可以通过如下方式即可存储:
pcl::PCDWriter writer; // save pcd file
// pcl::PLYWriter writer; // save ply file
writer.write<pcl::PointXYZI> (out_file, *points, false);
下面说一下pcd/ply转换为bin的方式:
// load point cloud file.
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
pcl::PCDReader reader;
reader.read<pcl::PointXYZI>(in_file.c_str(), *cloud); // get point cloud.
std::ofstream fout(out_file.c_str(), std::ios::binary); // IO stream for output.
for(int i=0; i < cloud->points.size(); i++)
{ // write cloud data to file with binary.
fout.write((char *)&cloud->points[i].x, sizeof(float));
fout.write((char *)&cloud->points[i].y, sizeof(float));
fout.write((char *)&cloud->points[i].z, sizeof(float));
fout.write((char *)&cloud->points[i].intensity, sizeof(float));
}
fout.close();
上述主要介绍一下点云数据文件的格式转换,bin2pcd/ply或者是pcd/ply2bin的相互转换。下面我贴一下完整的代码,主要读取点云文件并且进行转换:
void readKittiBin2Pcd(std::string& in_file, std::string& out_file)
{
// load point cloud file.
std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);
if (!input.good())
{
std::cerr << "Could not read file: " << in_file << std::endl;
exit(EXIT_FAILURE);
}
input.seekg(0, std::ios::beg);
pcl::PointCloud<pcl::PointXYZI>::Ptr points(new pcl::PointCloud<pcl::PointXYZI>);
int i;
for(i=0; input.good() && !input.eof(); i++)
{
pcl::PointXYZI point;
input.read((char *)&point.x, 3*sizeof(float));
input.read((char *)&point.intensity, sizeof(float));
points->push_back(point);
}
input.close();
std::cout << "Read KITTI point cloud with " << i << " points, writing to " << out_file << std::endl;
pcl::PCDWriter writer; // save pcd file format
// pcl::PLYWriter writer; // save ply file format
writer.write<pcl::PointXYZI> (out_file, *points, false);
}
void readKittiPcd2Bin(std::string& in_file, std::string& out_file)
{
// load point cloud file.
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
pcl::PCDReader reader;
reader.read<pcl::PointXYZI>(in_file.c_str(), *cloud);
std::cout << "cloud points size is: " << cloud->points.size() << std::endl;
std::ofstream fout(out_file.c_str(), std::ios::binary);
int i;
for(i=0; i < cloud->points.size(); i++)
{
fout.write((char *)&cloud->points[i].x, sizeof(float));
fout.write((char *)&cloud->points[i].y, sizeof(float));
fout.write((char *)&cloud->points[i].z, sizeof(float));
fout.write((char *)&cloud->points[i].intensity, sizeof(float));
}
fout.close();
std::cout << "Read KITTI point cloud with " << i << " points, writing to " << out_file << std::endl;
}
上面两个主要函数功能分别是bin转换pcd文件,和pcd转换bin文件的格式。相关ply文件与bin文件的相互转换与上述bin转换pcd基本类似,因此就不在赘述了。最后,如有错误,还请批评指正。
https://pcl.readthedocs.io/projects/tutorials/en/latest/reading_pcd.html#reading-pcd