PCL读写点云

PCL读写点云,第1张

 点云定义

根据激光测量原理得到的点云,包括三维坐标(XYZ)和激光反射强度(Intensity)。


根据摄影测量原理得到的点云,包括三维坐标(XYZ)和颜色信息(RGB)。


结合激光测量和摄影测量原理得到点云,包括三维坐标(XYZ)、激光反射强度(Intensity)和颜色信息(RGB)。


在获取物体表面每个采样点的空间坐标后,得到的是一个点的集合,称之为“点云”(Point Cloud)。


点云存储格式有很多:*.pts; *.asc ; *.dat; *.stl ; [1] *.imw;*.xyz;*.las LAS格式文件已成为LiDAR数据的工业标准格式,LAS文件按每条扫描线排列方式存放数据,包括激光点的三维坐标、多次回波信息、强度信息、扫描角度、分类信息、飞行航带信息、飞行姿态信息、项目信息、GPS信息、数据点颜色信息等。


PCL中点云的数据类型是PointCloud,它是一个C++类,包含了如下的数据成员(括号中是这个数据的数据类型):

(1)width(int) :指定了点云数据中的宽度。


width有两层含义:

- 对于无序点云而言, 指的是点云的数量。


- 在有序点云中,一行点云的数量。


(2)height(int) :指定了点云数据中的高度。


height有两层含义:

  • 指定有序点云中,点云行的数量。


  • 对于无序点云,将height设为1(它的width即为点云的大小),区分点云是否有序。


(3)points(std::vector) :points是存储类型为PointT的点的向量。


举例来说,对于一个包含XYZ数据的点云,points成员就是由pcl::PointXYZ类型的点构成的向量:

(4)is_dense(bool) :
指定点云中的所有数据都是有限的(true),还是其中的一些点不是有限的,它们的XYZ值可能包含inf/NaN 这样的值(false)。


(5)sensor_origin_(Eigen::Vector4f) :
指定传感器的采集位姿(==origin/translation==)这个成员通常是可选的,并且在PCL的主流算法中用不到。


(6)sensor_orientaion_(Eigen::Quaternionf) :
指定传感器的采集位姿(方向)。


这个成员通常是可选的,并且在PCL的主流算法中用不到。



为了简化开发,PointCloud类包含许多帮助成员函数。


举个例子,如果你想判断一个点云是否有序,不用检查height是否等于1,而可以使用isOrganized()函数来判断:

.使用point类型

由于pcl模块很多,为了提高编译速度,在组合中使PCL中已经定义的point类型所有的模块都能直接调用,不需要重新编译

方法:

在文件中首先声明我们的类和方法,再在模块类实现头文件中进行实现,配置在源文件中进行显示的实例,最后在编译链接时分别进行实例化

例子  

通过指针创建点云对象 的两种方式  

PCLPonitCloud2  和 PointCloud两种格式的点云对象 

实例化模板类PointCloud 每一个点的类型设置为pcl::PointXYZ

	pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
pcl::PCLPointCLOUD2 cloud;

PCL的example里通常都是这样定义点云:

pcl::PointCloud::Ptr cloud (new pcl::PointCloud );

如果要访问某一个点,则需要:

cloud->points[i].x

可以看到,points是个vector变量,所以points[i]就是单个的点,这里访问了他的x的值,同理可以访问y和z,如果想往cloud这个变量里面添加一个点的信息,则只需要定一个PointXYZ的变量,然后通过vector的push_back,加入到points这个变量里面

读写点云

1.PCDReader/PCGWriter

可以进行保存的pcd形式有ASCII Binary BinaryCompressed

#include 
#include 

using namespace std;

int main(int argc, char** argv)
{
    //模板点云
	pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
    //点云读取
	pcl::PCDReader reader;
	reader.read("data//bunny.pcd", *cloud);

	cout << "从点云数据中读取: " << cloud->width * cloud->height <<
		" 个, " << "数据中所包含的有效字段为: " << pcl::getFieldsList(*cloud) << endl;

	pcl::PCDWriter w;
	w.write("任意.pcd", false); // 第二个参数设置为false则保存为ASCII,设置为true则保存为Binary,默认参数为:false。


cerr << "保存为ASCII.形式 " << endl; w.writeASCII("ASCII.pcd", *cloud); // 保存速度较慢且保存后的文件较大 cerr << "保存为binary.形式" << endl; w.writeBinary("Binary.pcd", *cloud); // 保存速度较快 cerr << "保存为binary_compressed.形式" << endl; w.writeBinaryCompressed("binary_compressed.pcd", *cloud); // 保存速度较快且保存后的文件较小 return 0;

2.IO

可以进行保存的pcd形式有ASCII Binary BinaryCompressed

#include 
#include 

using namespace std;

int main(int argc, char** argv)
{
    #创建一个PointCloudboost共享指针并实现实例化
    #定义点云
	pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
    #打开点云文件
	if (pcl::io::loadPCDFile("data//bunny.pcd", *cloud) < 0)
	{
		PCL_ERROR("Could not read file\n");
		return (-1);
	}

	cout << "从点云数据中读取: " << cloud->width * cloud->height <<
		" 个, " <<"数据中所包含的有效字段为: " << pcl::getFieldsList(*cloud) << endl;

	cerr << "保存为ASCII.形式 " << endl;
	pcl::io::savePCDFile("任意.pcd", *cloud, false); // 第三个参数设置为false则保存为ASCII,设置为true则保存为Binary,默认参数为:false。


pcl::io::savePCDFileASCII("ASCII.pcd", *cloud); // 保存速度较慢且保存后的文件较大 cerr << "保存为binary.形式" << endl; pcl::io::savePCDFileBinary("Binary.pcd", *cloud); // 保存速度较快 cerr << "保存为binary_compressed.形式" << endl; pcl::io::savePCDFileBinaryCompressed("binary_compressed.pcd", *cloud); // 保存速度较快且保存后的文件较小 return 0; }

后缀命名为.ply格式文件,常用的点云数据文件。


ply文件不仅可以存储点数据,而且可以存储网格数据. 用编辑器打开一个ply文件,观察表头,如果表头element face的值为0,则表示该文件为点云文件,如果element face的值为某一正整数N,则表示该文件为网格文件,且包含N个网格.所以利用pcl读取 ply 文件,不能一味用pcl::PointCloud::Ptr cloud (new pcl::PointCloud)来读取。


在读取ply文件时候,首先要分清该文件是点云还是网格类文件。


如果是点云文件,则按照一般的点云类去读取即可,如果ply文件是网格类,则需要:

#include 

pcl::PolygonMesh mesh;
pcl::io::loadPLYFile("readName.ply", mesh);
pcl::io::savePLYFile("saveName.ply", mesh);

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/563614.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存