PCL使用

文章目录


在这里插入图片描述

#include <pcl/io/pcd_io.h> //PCD读写类相关头文件
#include <pcl/point_types.h> //PCL中支持的点类型头文件
#include <pcl/visualization/cloud_viewer.h>

using namespace pcl;

typedef pcl::PointXYZRGB PointT; //定义点云的每个点的类型;pcl::PointXYZRGBA :包括空间坐标XYZ以及颜色信息RGB,多了一个alpha通道;PointXYZHSV :空间位置 + HSV颜色空间表示的颜色
typedef pcl::PointCloud<PointT> PointClouds; //定义点云类,用于创建点云对象

PointClouds::Ptr cloud ( new PointClouds ); //用智能指针,创建一个空点云集

PointT p;

cloud->is_dense = false;   
pcl::io::savePCDFileBinary("Pointcloud.pcd", *cloud);

//清除数据并退出
cloud->points.clear(); 

//显示点云        
pcl::visualization::CloudViewer viewer( "viewer" );
viewer.showCloud( cloud );
while( !viewer.wasStopped() ) {}

//终端显示        
pcl_viewer pointcloud.pcd  //若只红绿蓝三个方块(是站在原点盯着坐标轴看),按R重置视角。如果点云没有颜色,按5显示颜色。
    
/*************彩色图+深度图(RGBD采集)******************/
for(图像){
    for(行){
        for(列){   
    /*
                p.z = double(d) / camera_factor;
                p.x = (n - camera_cx) * p.z / camera_fx;
                p.y = (m - camera_cy) * p.z / camera_fy;

                p.b = rgb.ptr<uchar>(m)[n*3];
                p.g = rgb.ptr<uchar>(m)[n*3+1];
                p.r = rgb.ptr<uchar>(m)[n*3+2];
                */
             cloud->points.push_back( p );
        }
    }
} 

        
   //或者用下面代替上句,效果一样 
    /*cloud->height = 1;
    cloud->width = cloud->points.size(); 
    pcl::io::savePCDFile( "./pointcloud.pcd", *cloud ); */

对点云滤波:点云中的噪声点对后续操作的影响比较大
一般下面这几种情况需要进行点云滤波处理:
(1) 点云数据密度不规则需要平滑
(2) 因为遮挡等问题造成离群点需要去除
(3) 大量数据需要下采样
(4) 噪声数据需要去除

滤波对应的方案有如下几种:
(1)按照给定的规则限制过滤去除点
(2)通过常用滤波算法修改点的部分属性
(3)对数据进行下采样

点云下采样:
640x480 的Depth图有30万个点,许多张图片进行融合,那储存、操作都是大问题!使用需要对大容量的样本,按一定的规则从里面抽取有代表性的样本,可以代替原来的样本。
下采样类:ApproximateVoxelGrid< PointT >适合对海量的点云在处理前进行数据压缩,就像我们上次讲的点云融合后的数据那样,而且可以在特征提取等处理中选择合适的体素(voxel)大小等参数,提高算法效率。该函数对输入的点云数据创建一个三维体素栅格,每个体素内用体素中所有点的重心来近似显示体素中其他点,这样该体素内所有点都用一个重心点最终表示。它的优点是可以在下采样的时候保存点云的形状特征。

// Voxel grid 滤波降采样
pcl::VoxelGrid<PointT> voxel; //创建滤波对象
voxel.setInputCloud( newCloud ); //设置需要过滤的点云给滤波对象
voxel.setLeafSize (0.01f, 0.01f, 0.01f);  //设置滤波时创建的体素栅格叶大小,分别表示体素在XYZ方向的尺寸,以米为单位
PointCloud::Ptr tmp( new PointCloud() );
voxel.filter( *tmp ); //执行滤波处理,存储输出tmp
setDownsampleAllData(bool downsample) //设置是否对所有的字段下采样。如:PointXYZRGB 点云类型,若只对XYZ(字段)下采样则设置为false,对所有信息下采样则设置为true

离群点会随着积累进行传导。列举两个常用的去除离群点的类:
StatisticalOutlierRemoval:使用统计分析技术,从一个点云数据中集中移除测量噪声点。计算每个点到所有相邻点的平均距离。假设得到的分布是高斯分布,可以计算出μ和σ,那么这个邻域点集中所有点与其邻域距离大于μ + std_mul * σ 的点都视为离群点,并从点云数据中去除。std_mul 是标准差倍数的一个阈值,可以自己指定。

pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建统计分析滤波器对象
sor.setInputCloud (cloud);  //设置待滤波的点云
sor.setMeanK (50);  //设置在进行统计时考虑的临近点个数,设置对每个点分析的临近点的个数设置为50
sor.setStddevMulThresh (1.0);  //设置判断是否为离群点的阀值std_mul,用来倍乘标准差,std_mul=1:如果一个点的距离超出了平均距离加上一个标准差以上,则移除
sor.filter (*cloud_filtered);  //滤波结果存储到cloud_filtered

RadiusOutlinerRemoval:设定每个点一定半径(欧氏距离,单位m)范围内至少有足够多的近邻点,若点数不够就会被删除

pcl::RadiusOutlierRemoval<pcl::PointXYZ> pcFilter;  //创建滤波器对象
pcFilter.setInputCloud(cloud);             //设置待滤波的点云
pcFilter.setRadiusSearch(0.8);               // 在0.8m半径范围内找近邻点
pcFilter.setMinNeighborsInRadius(2);      // 设置一个内点最少的邻居数目
pcFilter.filter(*cloud_filtered);        //滤波结果存储到cloud_filtered

点云平滑法线估计:
https://mp.weixin.qq.com/s?__biz=MzIxOTczOTM4NA==&mid=2247486705&idx=1&sn=ca333d7bb12b7c226270e98d0003a789&chksm=97d7e966a0a06070a8dba605966016d227d7a6cad786498070d9e1b8cea8747470a4840257fd&scene=21#wechat_redirect
用RGB-D,激光扫描仪等设备扫描物体,尤其是比较小的物体时,往往会有测量误差。这些误差所造成的不规则数据如果直接拿来曲面重建的话,会使得重建的曲面不光滑或者有漏洞,而且这种不规则数据很难用前面我们提到过的统计分析等滤波方法消除,所以为了建立光滑完整的模型必须对物体表面进行平滑处理和漏洞修复。还有一种情况也需要对点云进行平滑。就是后处理过程中,比如我们对同一个物体从不同方向进行了多次扫描,然后把扫描结果进行配准,最后得到一个完整的模型,但是你配准的结果不一定准啊,比如下图中左侧就是配准后未经过处理的结果,同一面墙壁由于配准误差变成了“两面墙”,并不能完全重叠如果这时候,我们没有条件重新扫描出更精确的结果,或者配准精度也无法提升,可以通过重采样的方法来实现点云的平滑,从而避免出现这样的问题。
如何通过重采样实现点云平滑?
通过一种叫做“移动最小二乘”(MLS, Moving Least Squares )法来实现的,对应的类名叫做:pcl::MovingLeastSquares,
// 对点云重采样
pcl::search::KdTree::Ptr treeSampling (new pcl::search::KdTree); // 创建用于最近邻搜索的KD-Tree
pcl::PointCloud mls_points; //输出MLS
pcl::MovingLeastSquares<PointT, PointT> mls; // 定义最小二乘实现的对象mls
mls.setComputeNormals (false); //设置在最小二乘计算中是否需要存储计算的法线
mls.setInputCloud (cloud_filtered); //设置待处理点云
mls.setPolynomialOrder(2); // 拟合2阶多项式拟合
mls.setPolynomialFit (false); // 设置为false可以 加速 smooth
mls.setSearchMethod (treeSampling); // 设置KD-Tree作为搜索方法
mls.setSearchRadius (0.05); // 单位m.设置用于拟合的K近邻半径
mls.process (mls_points); //输出

KD-Tree就是为了便于管理、搜索点云,这种结构来可以很方便的找到最近邻点。

如何估计点云的表面法线?
网格化前我们还需要估计一下点云的表面法线(normal)
尤其是在三维建模中应用非常广泛,比如在计算机图形学(computer graphics)领域里,法线决定着曲面与光源(light source)的强弱处理(Flat Shading),对于每个点光源位置,其亮度取决于曲面法线的方向。
点云的法线计算是稍微麻烦点,一般有两种方法:
1、使用曲面重建方法,从点云数据中得到采样点对应的曲面,然后再用曲面模型计算其表面的法线
2、直接使用近似值直接从点云数据集推断出曲面法线
这里主要用第2种方法来近似估计点云中每个点的表面法线。
具体来说,就是把估计某个点的表面法线问题简化为:从该点最近邻计算的协方差矩阵的特征向量和特征值的分析,这里就不多做介绍了。PCL已经帮我们封装好了函数啦
需要从该点的周围点邻域(也称为k邻域)估计一点处的表面法线 ,所以这个K邻域的选取也很关键

点云到网格的进化
之前处理的都是一个个点,不管是滤波还是平滑,我们都是对一个个离散的空间点进行的处理,虽然你远看能看出物体的轮廓,但是拉近了看是一个个分散的空间点
这样的结果分辨率比较低,也没办法进行三维打印,点云网格化就是用点云生成网格,最后得到的是一个连续(相对于前面的离散点)的表面。如果再加上纹理贴图,就能得到和真实物体一样的三维模型了

三角形表示网格也叫三角剖分。它有如下几个优点:

1、正如你所说的,稳定性强。

2、三角网格比较简单(主要原因),实际上三角网格是最简单的网格类型之一,可以非常方便并且快速生成,在非结构化网格中最常见。而且相对于一般多边形网格,许多操作对三角网格更容易。

3、有助于恢复模型的表面细节。

每个三角形都和其他三角形共享边。所以三角网格需要存储三类信息:

顶点。每个三角形都有三个顶点,各顶点都有可能和其他三角形共享。

边。连接两个顶点的边,每个三角形有三条边。

面。每个三角形对应一个面,我们可以用顶点或边列表表示面。

点云到网格的进化
https://mp.weixin.qq.com/s?__biz=MzIxOTczOTM4NA==&mid=2247486802&idx=1&sn=e765587e990fb0108a5ae673c7a6e641&chksm=97d7e8c5a0a061d3686f2c0e171a312b7fedda7e7af09277301920e246d21a05dae83a60c2b0&scene=21#wechat_redirect
https://www.cnblogs.com/li-yao7758258/category/954066.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python-PCL 是一个用于处理点云数据的 Python 绑定库。PCL(Point Cloud Library)是一个功能强大的开源点云处理库,提供了许多用于点云数据处理和分析的算法和工具。Python-PCL 将 PCL 的功能和性能与 Python 的简洁和易用性相结合,使得在 Python 中处理点云数据变得更加方便和高效。 首先,我们需要安装 Python-PCL 库。可以使用以下命令在 Python 环境中安装它: ``` pip install python-pcl ``` 安装完成后,我们可以导入 Python-PCL 库并开始使用它。在导入库之前,我们需要先导入点云数据。可以通过多种方式导入点云数据,比如从本地文件读取、从传感器获取等。一旦导入了点云数据,我们就可以使用 Python-PCL 库中提供的各种点云处理算法对数据进行处理。 Python-PCL 提供了多种点云处理功能,比如滤波、聚类、特征提取等。可以根据具体的需求选择合适的算法来处理点云数据。例如,可以使用滤波算法对点云数据进行降噪操作,使用聚类算法将点云数据划分为不同的物体,使用特征提取算法提取点云数据的特征等。 使用 Python-PCL 时,还可以使用其他 Python 数据处理和可视化库来增强功能。比如可以使用 NumPy 来对点云数据进行数组操作,使用 Matplotlib 来进行可视化展示等。 总而言之,Python-PCL 可以帮助我们方便地处理和分析点云数据,提供了许多强大的算法和工具。它的简洁易用性和与其他 Python 库的兼容性使得在 Python 中处理点云数据变得更加容易和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值