【pcl入门教程系列】之点云IO介绍及其转换

介绍

  点云存储文件格式有很多格式,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;
点云bin/pcd/ply之间的转换

  我们以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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCL点云转换为ROS点云格式需要进行以下步骤: 1. 创建一个ROS节点和发布者对象。 ```cpp ros::NodeHandle nh; ros::Publisher cloud_pub = nh.advertise<sensor_msgs::PointCloud2>("point_cloud", 1); ``` 2. 创建一个PCL点云对象和ROS点云对象。 ```cpp pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>); sensor_msgs::PointCloud2 ros_cloud; ``` 3. 将PCL点云对象转换为ROS点云对象。 ```cpp pcl::toROSMsg(*pcl_cloud, ros_cloud); ``` 4. 设置ROS点云对象的header信息。 ```cpp ros_cloud.header.frame_id = "base_link"; ros_cloud.header.stamp = ros::Time::now(); ``` 5. 发布ROS点云对象。 ```cpp cloud_pub.publish(ros_cloud); ``` 完整代码示例: ```cpp #include <ros/ros.h> #include <sensor_msgs/PointCloud2.h> #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> int main(int argc, char **argv) { // 初始化ROS节点 ros::init(argc, argv, "pcl_to_ros_publisher"); ros::NodeHandle nh; // 创建发布者对象 ros::Publisher cloud_pub = nh.advertise<sensor_msgs::PointCloud2>("point_cloud", 1); // 创建PCL点云对象 pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>); // 填充PCL点云对象 // 将PCL点云对象转换为ROS点云对象 sensor_msgs::PointCloud2 ros_cloud; pcl::toROSMsg(*pcl_cloud, ros_cloud); // 设置ROS点云对象的header信息 ros_cloud.header.frame_id = "base_link"; ros_cloud.header.stamp = ros::Time::now(); // 发布ROS点云对象 cloud_pub.publish(ros_cloud); // 循环等待 ros::spin(); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值