PCL学习笔记(一)——从PCD文件中读取点云数据

初学PCL,基础为零,根据《点云库PCL学习教程》进行的学习,但是对于零基础的我来说,还是参考了网上多位大神的心得才成功运行了第一个示例程序,因此在这里总结一下遇到的问题,仅供其他零基础伙伴参考,个中错误不足之处也请大家不吝赐教。

就是使用下边的示例程序进行的学习。

#include 
#include 
#include 

int
main(int argc,char** argv)
{
pcl::PointCloud::Ptr cloud (new pcl::PointCloud);

if(pcl::io::loadPCDFile("test_pcd.pcd",*cloud)==-1)//*打开点云文件
{
PCL_ERROR("Couldn't read file test_pcd.pcd\n");
return(-1);
}
std::cout<<"Loaded "
<width*cloud->height
<<" data points from test_pcd.pcd with the following fields: "
<points.size();++i)
std::cout<<"    "<points[i].x
<<" "<points[i].y
<<" "<points[i].z<

下面开始逐语句介绍:

一、头文件

#include 
#include 
#include 

这是与程序相关的头文件,没有做深入研究。

二、创建指针

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

总的来说,这条语句的作用就是创建了一个名为cloud的指针,储存XYZ类型的点云数据。

PointCloud是PCL中的一个基类,pcl::PointCloud::Ptr是一个Boost共享指针(我的理解是这个指针是基于这个基类得到的)。这个共享指针究竟是怎么得到的呢?是这样子:

typedef boost::shared_ptr > pcl::PointCloud< T >::Ptr

1.继承是用已有数据类型创建新的数据类型,并保留已有数据类型的特点,以旧类为基础创建新类,新类包含了旧类的数据成员和成员函数。旧类就是基类,新类被称作派生类。

2.typedef 是C语言关键字,为一种是数据类型定义一个新名字。在这个程序中,pcl::PointCloud< T >::Ptr 就是共享指针的新名字。

3.Boost::shared_ptr是一个共享指针,用来管理动态创建的对象的销毁。可以使用new直接创建一个共享指针:

shared_ptr ptr(new T())

T代表的是共享指针所指向的对象的类型,在本文中,共享指针指向的是PointT类型。

new pcl::PointCloud

是给了一个地址,初始化指针。

三、读取pcd文件

if(pcl::io::loadPCDFile("test_pcd.pcd",*cloud)==-1)//*打开点云文件
{
PCL_ERROR("Couldn't read file test_pcd.pcd\n");
return(-1);
}

这条语句的含义是:如果没有读取到名为“test_pcd.pcd”的文件,返回-1。

1.返回值类型分为int型和布尔型。布尔型的返回值分为0和1,0表示假,1表示真。int型的返回值是0和-1,0表示成功完成函数,-1表示函数完成失败。

2.很多程序主函数也有返回值,其实,main()返回值不是返回给程序其他部分,而是返回给操作系统。

四、输出

std::cout<<"Loaded "
<width*cloud->height
<<" data points from test_pcd.pcd with the following fields: "
<points.size();++i)
std::cout<<"    "<points[i].x
<<" "<points[i].y
<<" "<points[i].z<

这两条语句完成的是对点云数据的输出。

1.->表示成员提取,A->B表示提取A中的成员B。A只能是指向类、结构、联合的指针。

2.width、height、points,都是PointCloud中的数据域。

(1)width(int),如果是无组织,无结构的点云数据,表示点云的个数;如果是有结构的点云数据,表示点云数据集一行的点数。

(2)height(int),如果是无结构的点云数据,height=1;如果是有结构的点云数据,height表示点云总行数。

(3)points(std::vector)存储了数据类型为PointT的一个动态数组。

3.PointXYZ 是最常见的一个点数据类型,它只包含三维X,Y,Z坐标信息。如果要表示x坐标,可以表示为

(1)points[i].data[0];

(2)points[i].x。

4.size_t 整型,保存一个整数,记录一个大小(size)。

5.points.size() 表示点云数据大小。

以上就是我对程序内容的理解。

下面整理一下调试中遇到的问题。

五、调试

1.出现了 LINK : fatal error LNK1104: 无法打开文件“C:\Qt\4.8.0\lib\QtGuid4.lib”

解决方法:工程名称(右键)——属性——链接器——输入——附加依赖项,删除C:Qt/……相关的内容。

2.无法查找或打开PDB文件

解决方法:工具——选项——调试——常规——勾选启用源服务器支持,工具——选项——调试——符号——勾选符号服务器。

3.读取不到pcd文件

解决方法:将pcd文件的路径写为绝对路径,E:\\PCL\\……\\test_pcd.pcd。

文件路径\和\\的区别

Windows下文件路径是用\分隔;C语言中,文件路径会被写作字符串形式,但是由于C语言的字符串规划中,\字符是转义字符的引导,所以直接用\分隔路径会出错,必须用\\。

4.exe文件闪退

解决方法:加头文件#include

程序末尾,return(0)之前添加system("pause");

 

不太理解argc和argv的含义,去掉之后,对程序没有影响。

最终成功运行的程序为:

#include 
#include 
#include 
#include 

int
main()
{
pcl::PointCloud::Ptr cloud (new pcl::PointCloud);

if(pcl::io::loadPCDFile("E:\\job\\PCLbook\\example\\pcd_read\\source\\test_pcd.pcd", *cloud)==-1)//*打开点云文件
{
PCL_ERROR("Couldn't read file test_pcd.pcd\n");
return(-1);
}
std::cout<<"Loaded "
<width*cloud->height
<<" data points from test_pcd.pcd with the following fields: "
<points.size();++i)
std::cout<<"    "<points[i].x
<<" "<points[i].y
<<" "<points[i].z<

 

你可能感兴趣的:(PCL学习笔记(一)——从PCD文件中读取点云数据)