PCL常用代码总结(一):文件操作 & 类型转换

1. 打开ply/pcd文件(pcl::PointCloud <PointT>)

#include <pcl/io/pcd_io.h> 
#include <pcl/io/ply_io.h>
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>

// 【1】定义帮助函数
void
showHelp(char * program_name)
{
  std::cout << std::endl;
  std::cout << "Usage: " << program_name << " cloud_filename.[pcd|ply]" << std::endl;
  std::cout << "-h:  Show this help." << std::endl;
}

// 主函数
int
main (int argc, char** argv)
{

  // 输入‘-h’或者输入参数错误时,显示帮助函数
  if (pcl::console::find_switch (argc, argv, "-h") || pcl::console::find_switch (argc, argv, "--help")) {
    showHelp (argv[0]);
    return 0;
  }

  // Fetch point cloud filename in arguments | Works with PCD and PLY files
  std::vector<int> filenames;
  bool file_is_pcd = false;

//【2】从输入参数中得到文件名字filenames

  filenames = pcl::console::parse_file_extension_argument (argc, argv, ".ply");
  //如果不是ply文件则检测是否为pcd文件
  if (filenames.size () != 1)  {
    //根据输入的参数,寻找后缀为pcd的参数名字,找到为1
    filenames = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");
    //如果不是pcd文件,表示没有找到此文件
    if (filenames.size () != 1) {
      showHelp (argv[0]);
      return -1;
    } else {
      file_is_pcd = true;
    }
  }

//【3】加载ply或者pcd文件

  pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud (new pcl::PointCloud<pcl::PointXYZ> ());

  if (file_is_pcd) {
    if (pcl::io::loadPCDFile (argv[filenames[0]], *source_cloud) < 0)  {
      std::cout << "Error loading point cloud " << argv[filenames[0]] << std::endl << std::endl;
      showHelp (argv[0]);
      return -1;
    }
  } else {
    if (pcl::io::loadPLYFile (argv[filenames[0]], *source_cloud) < 0)  {
      std::cout << "Error loading point cloud " << argv[filenames[0]] << std::endl << std::endl;
      showHelp (argv[0]);
      return -1;
    }
  }
  
//【4】其他处理程序
/** 
 *下面开始对点云数据source_cloud进行操作
 */
}

以上是通过loadPCDFileloadPLYFile函数来读取点云文件,同样可以直接通过reader.read来读取保存为PCLPointCloud2类型的数据,见下面的PCLPointCloud2和PointCloud一节。

2. 创建随机点云数据(pcl::PointCloud <PointT>)

#include <pcl/point_types.h>

pcl::PointCloud<pcl::PointXYZ> cloud;
// 【1】设置点云长宽和密集型参数
cloud.width=5;
cloud.height=1; //如果是无序点云,则高度设为1
cloud.is_dense=false; //false代表没有NaN/Inf值的点,也就是“非密集型”
cloud.points.resize(cloud.width*cloud.height);

//【2】随机赋值点云数据
for(size_t i=0;i<cloud.points.size();++i)
{
cloud.points[i].x=1024*rand()/(RAND_MAX+1.0f);
cloud.points[i].y=1024*rand()/(RAND_MAX+1.0f);
cloud.points[i].z=1024*rand()/(RAND_MAX+1.0f);
}
  • rand函数的定义:
    extern int rand (void) __THROW;
    意思是返回一个包括0RAND_MAX在内的随机整数值。__THROW表示该函数不会抛出异常,只在Linux的C++程序中应用。

  • RAND_MAX的宏定义:#define RAND_MAX 2147483647

3. 保存ply/pcd文件(pcl::PointCloud <PointT>)

两种数据类型存储:ASSIC码和Binary,ASSIC格式文件是先转换为字符再保存因此文件可以直接打开,Binary格式是直接保存字节文件,因此性能更高,但是不能直接打开查看数据。

  • 保存点云数据至PCD文件中:
#include <pcl/io/pcd_io.h>

//保存ASCII格式文件至PCD文件中
pcl::io::savePCDFileASCII("test_pcd.pcd",cloud); 
//保存Binary格式文件至PCD文件中
pcl::io::savePCDFileBinary("test_pcd.pcd",cloud); 
//保存一个经过压缩后的Binary格式文件
pcl::io::savePCDFileBinaryCompressed("test_pcd.pcd",cloud); 
  • 保存点云数据至PLY文件中:
#include <pcl/io/ply_io.h>

//保存ASCII格式文件至PLY文件中
pcl::io::savePLYFileASCII("test_pcd.ply",cloud); 
//保存Binary格式文件至PLY文件中
pcl::io::savePLYFileBinary("test_pcd.ply",cloud); 

4. pcl::PCLPointCloud2常用接口

PCLPointCloud2是为ROS设计的数据格式,是一个结构体,位于PCLPointCloud2.h头文件中。常用于PCD与PLY文件的互换过程。

//【1】常用的成员变量
pcl::uint32_t height;
pcl::uint32_t width;
std::vector<pcl::uint8_t> data;
pcl::uint8_t is_dense;

//【2】获取通道
//c_str是将string变量转为char*。以下输出x y z
print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

//【3】读取点云数据存到PointCloud2格式变量
pcl::PCLPointCloud2 cloud;
pcl::PLYReader reader;
if (reader.read (filename, cloud) < 0)
    return (false);

//【4】保存点云数据    
//下面write这个函数filename是string类型的文件名字,format为1代表保存二进制,0为ASCII
pcl::PCDWriter writer;
writer.write (filename, cloud, Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), format);

☆附录:

A. PointT常用类型

pcl::PointXYZ //float x, y, z
pcl::PointXYZRGB //float x, y, z, rgb
pcl::PointNormal //float x, y, z; float normal[3], curvature
pcl::PointXYZRGBNormal //float x, y, z, rgb, normal[3], curvature

B. PCL中打印输出

  • PCL输出接口
#include <pcl/console/print.h>

PCL_ERROR("Couldn't read file test_pcd.pcd\n");
PCL_INFO("Couldn't read file test_pcd.pcd\n");
PCL_WARN("Couldn't read file test_pcd.pcd\n");
  • print输出接口
#include <pcl/console/print.h>

print_info ("Available dimensions: "); //输出字符串
print_value ("%s\n", pcl::getFieldsList (cloud).c_str ()); //输出格式化字符串
  • 标准输出接口
#include <iostream>

//standard error
std::cerr<<"Saved "<<cloud.points.size()<<" data points to test_pcd.pcd."<<std::endl;

C. 参数读取函数

#include <pcl/console/parse.h>

//【1】用来判断是否有后缀为‘.ply’的参数,若有则为1
pcl::console::parse_file_extension_argument (argc, argv, ".ply");

//【2】用来寻找"-format"参数,并将值赋给format
parse_argument (argc, argv, "-format", format);

☆参考:

https://pcl.readthedocs.io/projects/tutorials/en/latest/index.html
https://www.cnblogs.com/li-yao7758258/p/6659451.html
https://blog.csdn.net/qq_27806947/article/details/89416355
https://book.douban.com/subject/30659047/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值