PCL学习笔记一

一、概念和应用:

PCL点云库(Point Cloud Library)简介_pointcloudlibrary android_hellohake的博客-CSDN博客

PCL点云库(Point Cloud Library)简介

什么是PCL

PCL(Point Cloud Library)是在吸收了前人点云相关研究基础上建立起来的大型跨平台开源C++编程库,它实现了大量点云相关的通用算法和高效数据结构,涉及到点云获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。支持多种操作系统平台,可在Windows、Linux、Android、Mac OS X、部分嵌入式实时系统上运行。如果说OpenCV是2D信息获取与处理的结晶,那么PCL就在3D信息获取与处理上具有同等地位,PCL是BSD授权方式,可以免费进行商业和学术应用。

PCL的发展与创景

PCL起初是ROS(Robot Operating System)下由来自于慕尼黑大学(TUM - Technische Universität München)和斯坦福大学(Stanford University)Radu博士等人维护和开发的开源项目,主要应用于机器人研究应用领域,随着各个算法模块的积累,于2011年独立出来,正式与全球3D信息获取、处理的同行一起,组建了强大的开发维护团队,以多所知名大学、研究所和相关硬件、软件公司为主,可参考图1。截止目前,发展非常迅速,不断有新的研究机构等加入,在Willow Garage, NVidia, Google (GSOC 2011), Toyota, Trimble, Urban Robotics, Honda Research Institute等多个全球知名公司的资金支持下,可参考图1,不断提出新的开发计划,代码更新非常活跃,至今在不到一年的时间内从1.0版本已经发布到1.7.0版本。

PCL学习笔记一_第1张图片

图1 加入或资助PCL的开发组织、研究所、公司

PCL学习笔记一_第2张图片

图2 加入PCL开发的组织全球地理分布

PCL是集体智慧的结晶,是大家共同努力的结果。如果没有这些人的贡献,也就不可能有PCL的出现,笔者在此表示无比敬仰。

随着加入组织的增多,PCL官方目前的计划是继续加入很多新的功能模块和算法的实现,包括当前最新的3D相关的处理算法,如基于PrimeSensor 3D设备,微软Kinect或者华硕的XTionPRO智能交互应用等,详细读者可以参考官方网站每期的新闻,而且也计划进一步支持使用CUDA 和OpenCL等基于GPU的高性能计算的技术。笔者相信在近几年内会有更多的人和组织加入到这个项目中来,共享开源PCL带来的各自领域的成果。

PCL的潜在应用领域

前面讲述了,在这么短时间,如此多的组织个人和公司加入到PCL开源项目中来,为什么?PCL能解决什么问题呢?

机器人领域

移动机器人对其工作环境的有效感知、辨识与认知,是其进行自主行为优化并可靠完成所承担任务的前提和基础。如何实现场景中物体的有效分类与识别是移动机器人场景认知的核心问题,目前基于视觉图像处理技术来进行场景的认知是该领域的重要方法。但移动机器人在线获取的视觉图像质量受光线变化影响较大,特别是在光线较暗的场景更难以应用,随着RGBD获取设备的大量推广,在机器人领域势必掀起一股深度信息结合2D信息的应用研究热潮,深度信息的引入能够使机器人更好地对环境进行认知、辨识,与图像信息在机器人领域的应用一样,需要强大智能软件算法支撑,PCL就为此而生,最重要的是PCL本身就是为机器人而发起的开源项目,PCL中不仅提供了对现有的RGBD信息的获取设备的支持,还提供了高效的分割、特征提取、识别、追踪等最新的算法,最重要的是它可以移植到android、ubuntu等主流Linux平台上,PCL无疑将会成为机器人应用领域一把瑞士军刀。

CAD/CAM、逆向工程

大部分工业产品是根据二维或三维CAD模型制造而成,但有时因为数据丢失、设计多次更改、实物引进等原因,产品的几何模型无法获得,因而常常需要根据现有产品实物生成物体几何模型。逆向工程技术能够对产品实物进行测绘,重构产品表面三维几何模型,生成产品制造所需的数字化文档。在一些工业领域,如汽车制造业,许多零件的几何模型都通过逆向工程由油泥模型或实物零件获得,目前在CAD/CAM领域利用激光点云进行高精度测量与重建成为趋势,同时引来了新的问题,通过获取的海量点云数据,来提取重建模型的几何参数,或者形状模型,对模型进行智能检索,从点云数据获取模型的曲面模型等,诸如此类的问题解决方案在PCL中都有涉及。例如kdtree和octree对海量点云进行高效压缩存储与管理,其中滤波、配准、特征描述与提前基础处理,可以应用于模型的智能检索,以及后期的曲面重建和可视化都在PCL中有相应的模块。总之,三维点云数据的处理是逆向工程中比较重要的一环,PCL中间所有的模块正是为此而生的。

激光遥感测量

能够直接获取高精度三维地面点数据,是对传统测量技术在高程数据获取及自动化快速处理方面的重要技术补充。激光遥感测量系统在地形测绘、环境检测、三维城市建模、地球科学、行星科学等诸多领域具有广泛的发展前景,是目前最先进的能实时获取地形表面三维空间信息和影像的遥感系统。目前,在各种提取地面点的算法中,算法结果与世界结果之间差别较大,违背了实际情况,PCL中强大的模块可以助力此处的各种需求。

虚拟现实、人机交互

虚拟现实技术(简称VR),又称灵境技术,是以沉浸性、交互性和构想性为基本特征的计算机高级人机界面。它综合利用了计算机图形学、仿真技术、多媒体技术、人工智能技术、计算机网络技术、并行处理技术和多传感器技术,模拟人的视觉、听觉、触觉等感觉器官功能,使人能够沉浸在计算机生成的虚拟境界中,并能够通过语言、手势等自然的方式与之进行实时交互,创建了一种适人化的多维信息空间,具有广阔的应用前景。目前各种交互式体感应用的推出,让虚拟现实与人机交互发展非常迅速,以微软、华硕、三星等为例,目前诸多公司推出的RGBD解决方案,势必会让虚拟现实走出实验室,因为现有的RGBD设备已经开始大量推向市场,只是缺少,其他应用的跟进,这正是在为虚拟现实和人机交互应用铸造生态链的底部,笔者认为这也正是PCL为何在此时才把自己与世人分享的重要原因所在,它将是基于RGBD设备的虚拟现实和人机交互应用生态链中最重要的一个环节。让我们抓住这一个节点,立足于交互式应用的一片小天地,但愿本书来的不是太迟。

PCL在中国

PCL虽然在国际上,有如此多的组织和公司参与,由于发展如此迅速,目前在google中检索出中文相关的PCL探讨,有且只有一条,当然这也是笔者出书原因之一了,事实上,如图1.2所示,在全球范围内,唯独在中国的版块上,没有参与组织,这里希望广大读者,可以为中国板块上添加一个小旗帜。当然,肯定有科研工作者的在应用或者学习PCL了,笔者依托于中国农业大学、农业部信息获取重点实验室,在与创始人Ruda博士交流后,深感PCL在复杂的农业对象中有不可估量的作用,例如对动植物的重建测度、果蔬等分级检测等应用领域,决定把PCL作为基础研究平台来开展实际应用。同时用学习笔记撰写了本书,把PCL与国人分享,相信在不久的将来,与2D信息处理库OpenCV一样,中国将是PCL最大的用户和贡献者基地。

PCL的结构和内容

如图3PCL架构图所示,对于3D点云处理来说,PCL完全是一个的模块化的现代C++模板库。其基于以下第三方库:Boost、Eigen、FLANN、VTK、CUDA、OpenNI、Qhull,实现点云相关的获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。

PCL利用OpenMP、GPU、CUDA等先进高性能计算技术,通过并行化提高程序实时性。K近邻搜索操作的构架是基于FLANN (Fast Library for Approximate Nearest Neighbors)所实现的,速度也是目前技术中最快的。PCL中的所有模块和算法都是通过Boost共享指针来传送数据的,因而避免了多次复制系统中已存在的数据的需要,从0.6版本开始,PCL就已经被移入到Windows,MacOS和Linux系统,并且在Android系统也已经开始投入使用,这使得PCL的应用容易移植与多方发布。

PCL学习笔记一_第3张图片

                                                                                        图3 PCL架构图

从算法的角度,PCL是指纳入了多种操作点云数据的三维处理算法,其中包括:过滤,特征估计,表面重建,模型拟合和分割,定位搜索等。每一套算法都是通过基类进行划分的,试图把贯穿整个流水线处理技术的所有常见功能整合在一起,从而保持了整个算法实现过程中的紧凑和结构清晰,提高代码的重用性、简洁可读。在PCL中一个处理管道的基本接口程序是:

创建处理对象:(例如过滤、特征估计、分割等);

使用setInputCloud通过输入点云数据,处理模块;

设置算法相关参数;

调用计算(或过滤、分割等)得到输出。

为了进一步简化和开发,PCL被分成一系列较小的代码库,使其模块化,以便能够单独编译使用提高可配置性,特别适用于嵌入式处理中:

libpcl filters:如采样、去除离群点、特征提取、拟合估计等数据实现过滤器;

libpcl features:实现多种三维特征,如曲面法线、曲率、边界点估计、矩不变量、主曲率,PFH和FPFH特征,旋转图像、积分图像,NARF描述子,RIFT,相对标准偏差,数据强度的筛选等等;

libpcl I/O:实现数据的输入和输出操作,例如点云数据文件(PCD)的读写;

libpcl segmentation:实现聚类提取,如通过采样一致性方法对一系列参数模型(如平面、柱面、球面、直线等)进行模型拟合点云分割提取,提取多边形棱镜内部点云等等;

libpcl surface:实现表面重建技术,如网格重建、凸包重建、移动最小二乘法平滑等;

libpcl register:实现点云配准方法,如ICP等;

libpclkeypoints:实现不同的关键点的提取方法,这可以用来作为预处理步骤,决定在哪儿提取特征描述符;

libpcl range :实现支持不同点云数据集生成的范围图像。

为了保证PCL中操作的正确性,上述提到的库中的方法和类包含了单位和回归测试。这套单元测试通常都是由专门的构建部门按需求编译和验证的。当某一部分测试失败时,这些特定部分的各自作者就会立即被告知。这彻底地保证了代码测试过程出现的任何变故,以及新功能或修改都不会破坏PCL中已经存在的代码。

PCL 点云库 3D感知 NLP学习资源_pcl缺陷检测_锦鲤少年丶的博客-CSDN博客

PCL点云数据处理-滤波基础(C++)

PCL库中包含几个重要的模块库:FIilter(过滤器)、Features(特征)、Keypoints(关键点)、Registration(配准)、Kd-tree、Octree(八叉树)、Segementation(分割)、Sample consensus(样本一致性)、Surface(表面)、Range image(深度图)、I/O(输入输出)、Visualization(可视化)、Common(公共)、Search(搜索)

Filter模块库:去除点云中不需要的点和点云的投影。

下面用不同方法对点云进行滤波处理:

目录

Passthrough Filter(直通滤波):
VoxelGrid Filter(体素化网格滤波):
StatisticalOutlierRemoval(统计学的(稀疏)离群点去除):
Projecting points using a parameter model(投影滤波):
Extracting indices from a PointCloud(点云索引提取点云子集):
RadiusOutlierRemoval或ConditionalRemoval滤波器:
1.Passthrough Filter(直通滤波):限定某个字段(理解为点云的变量参数)的范围来达到去除异常点效果关键:

步骤:输入点云-创建滤波器对象-设置字段范围-保存滤波后点云

头文件:#include
 

头文件:#include
 
代码:pcl::PassThroughpass;//创建滤波器对象
      pass.setInputCloud(cloud);          //调用成员函数输入点云,cloud为已创建的点云对象
      pass.setFilterFieldName("z");       //调用设置字符串函数,z为设定字段对应字符串
      pass.setFilterLimits(0,2.0);        //调用范围设置函数,z的范围在0-2
      pass.filter(*cloud_filtered);      //执行直通过滤,并将执行结果被保存在cloud_filtered


 完整代码(直通滤波):

#include 
#include 
#include 
#include 
 
int main(int argc, char** argv)
{
    srand(time(0));
    //创建点云
    pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
    pcl::PointCloud::Ptr cloud_filtered(new pcl::PointCloud);
    //填入点云数据
    cloud->width = 5;
    cloud->height = 1;
    cloud->points.resize(cloud->width * cloud->height);
    for (size_t i = 0; i < cloud->points.size(); ++i)
    {
        cloud->points[i].x = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].y = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
    }
 
      std::cerr << "Cloud before filtering: " << std::endl;
    for (const auto& point : *cloud)
        std::cerr << "    " << point.x << " "
        << point.y << " "
        << point.z << std::endl;
 
    //直通滤波----
    pcl::PassThrough pass;
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0,1.0);
    pass.filter(*cloud_filtered);
    //滤波结束,结果保存在cloud_filtered
 
    std::cerr << "Cloud after filtering: " << std::endl;
    for (const auto& point : *cloud_filtered)
        std::cerr << "    " << point.x << " "
        << point.y << " "
        << point.z << std::endl;
    return (0);
}

执行结果

Cloud before filtering:
    -0.0164185 -0.177155 0.0244751
    -0.194244 0.169983 -0.147095
    0.277649 -0.317963 -0.36441
    0.166901 0.220856 0.144196
    -0.467896 0.15387 -0.345825
Cloud after filtering:
    -0.0164185 -0.177155 0.0244751
    0.166901 0.220856 0.144196
2.VoxelGrid Filter(体素化网格滤波):创建一个3D体素网格,每个体素中所有点将由质心来代替,将体素想象为立方体。

步骤:输入点云-创建滤波器对象-设置立方体大小-保存滤波后点云-可视化

头文件:#include 
 
代码:#include 
#include 
#include 
#include 
#include 
#include 
#include
#include 
using namespace std;
typedef pcl::PointXYZ PointT;
 
int main(int argc, char** argv)
{
	pcl::PointCloud::Ptr cloud(new pcl::PointCloud);			//待滤波点云
	///读入点云数据
	cout << "->正在读入点云..." << endl;
	/*pcl::io::loadPCDFile("rabbit.pcd", *cloud);*/
	pcl::PCDReader reader;
	reader.read("E:\\PCLNotes\\practice\\rabbit.pcd", *cloud);
	cout << "\t\t<读入点云信息>\n" << *cloud << endl;
	pcl::PointCloud::Ptr cloud_filtered(new pcl::PointCloud);	//滤波后点云
	///体素滤波器点云下采样
	cout << "->正在体素下采样..." << endl;
	pcl::VoxelGrid vg;		//创建滤波器对象
	vg.setInputCloud(cloud);				//设置待滤波点云
	vg.setLeafSize(1.15f, 1.15f, 1.15f);	//设置体素大小
	vg.filter(*cloud_filtered);			//执行滤波,保存滤波结果于cloud_filtered
 
	///保存下采样点云
	cout << "->正在保存下采样点云..." << endl;
	pcl::PCDWriter writer;
	writer.write("sub.pcd", *cloud_filtered, true);
	cout << "\t\t<保存点云信息>\n" << *cloud_filtered << endl;
	/*return 0;
	}*/
	//================================= 滤波前后对比可视化 ================================= 
 
	/*pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("滤波前后对比"));*/
	boost::shared_ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->initCameraParameters();//初始化相机参数
	/*-----视口1-----*/
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
	viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
	viewer->addText("befor_filtered", 10, 10, "v1_text", v1);
	viewer->addPointCloud(cloud, "befor_filtered_cloud", v1);
 
	/*-----视口2-----*/
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
	viewer->addText("after_filtered", 10, 10, "v2_text", v2);
	viewer->addPointCloud(cloud_filtered, "after_filtered_cloud", v2);
 
	/*-----设置相关属性-----*/
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "befor_filtered_cloud", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "befor_filtered_cloud", v1);
 
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "after_filtered_cloud", v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "after_filtered_cloud", v2);
 
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
 
 
	return 0;
}

执行结果:

PCL学习笔记一_第4张图片

 

 

问题:

 

 解决方法:https://blog.csdn.net/huhu7777/article/details/125358022

原文链接:https://blog.csdn.net/huhu7777/article/details/125323723

 K-D Tree 与 八叉树

【笔记】【点云PCL从入门到精通】第四章 K-D Tree 与 八叉树_点云库pcl从入门到精通 pdf_zhy29563的博客-CSDN博客

PCL学习笔记(二):PCL官方教程学习_pcl 教程_Sakurazzy的博客-CSDN博客

首推:

PCL(Point Cloud Library)学习指南&资料推荐(2023版) - 知乎 (zhihu.com)

你可能感兴趣的:(学习,笔记)