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进行操作
*/
}
以上是通过loadPCDFile
和loadPLYFile
函数来读取点云文件,同样可以直接通过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;
意思是返回一个包括0和RAND_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.youkuaiyun.com/qq_27806947/article/details/89416355
https://book.douban.com/subject/30659047/