点云基础学习

记录一下学习过程,方便回看,持续更新。 

网站推荐

黑马机器人 | PCL-3D点云

PCL(Point Cloud Library)学习记录(2023) · 语雀

还有就是官网的文档 

00PCL基础总结

在PCL中一个处理管道的基本接口程序如下:

  1. 创建处理对象〈例如过滤、特征估计、分割等).
  2. 使用setlnputCloud通过输入点云数据,处理模块.
  3. 设置算法相关参数
  4. 调用计算(或过滤、分割等〉得到输出.

编译运行步骤(在编译文件下打开目录)

mkdir build

cd build

cmake ..

make

./<文件名(pcd_write_test)>  //在build文件下运行

pcl_viewer <文件名(test_pcd.pcd )>  //查看pcd文件

pcl_viewer: 

Syntax is: pcl_viewer . , where options are:

-bc r,g,b = background color 背景颜色

-fc r,g,b = foreground color  前景颜色

-ps X = point size (1..64)  点云点大小

-opaque X = rendered point cloud opacity (0..1)   透明度

-ax n = enable on-screen display of XYZ axes and scale them to n    启用 XYZ 轴的屏幕显示并将其缩放到 n

-ax_pos X,Y,Z = if axes are enabled, set their X,Y,Z position in space (default 0,0,0)  如果启用了轴,则设置其在空间中的 X,Y,Z 位置(默认为 0,0,0)

-cam (*) = use given camera settings as initial view   使用给定的相机设置作为初始视图   ctrl+s保存  ctrl+h查看隐藏文件

(*) [Clipping Range / Focal Point / Position / ViewUp / Distance / Field of View Y / Window Size / Window Pos] or use a that contains the same information.   保存的参数

-multiview 0/1 = enable/disable auto-multi viewport rendering (default disabled)   多视图

-normals 0/X = disable/enable the display of every Xth point’s surface normal as lines (default disabled) -normals_scale X = resize the normal unit vector size to X (default 0.02)

-pc 0/X = disable/enable the display of every Xth point’s principal curvatures as lines (default disabled) -pc_scale X = resize the principal curvatures vectors size to X (default 0.02)

(Note: for multiple .pcd files, provide multiple -{fc,ps,opaque} parameters; they will be automatically assigned to the right file)

(注意:对于多个.pcd文件,请提供多个-{fcpsopaque}参数;它们将自动分配给正确的文件)

mesh2pcd: convert a CAD model to a PCD (Point Cloud Data) file, using ray tracing operations.

Syntax is: mesh2pcd input.{ply,obj} output.pcd , where options are:

-level X = tessellated sphere level (default: 2)

-resolution X = the sphere resolution in angle increments (default: 100 deg)

-leaf_size X = the XYZ leaf size for the VoxelGrid – for data reduction (default: 0.010000 m

mesh2pcd:使用光线追踪操作将 CAD 模型转换为 PCD(点云数据)文件。

语法为:mesh2pcd 输入。{ply,obj} output.pcd ,其中选项是:

-等级 X = 细分球体等级(默认值:2)

-分辨率 X = 以角度增量表示的球体分辨率(默认值:100 度)

-leaf_size X = VoxelGrid 的 XYZ 叶大小 – 用于数据缩减(默认值:0.010000 m

分辨率越高,数据量越大

02 KDTree

KD树生成:【数学】kd 树算法之详细篇 - 知乎

索引结构中相似性查询有两种基本的方式:一种是范围查询(range searches),另一种是K近邻查询(K-neighbor searches)

  1. 范围查询(range searches):给定查询点和查询距离的阈值,从数据集中找出所有与查询点距离小于阈值的数据
  2. K近邻查询(K-neighbor searches):给定查询点及正整数K,从数据集中找到距离查询点最近的K个数据,当K=1时,就是最近邻查询(nearest neighbor searches)。

代码

#include

#include

#include // 包含kdtree头文件

typedef pcl::PointXYZ PointT;

int main()

{

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

       pcl::io::loadPCDFile("read.pcd", *cloud);

       // 定义KDTree对象

       pcl::search::KdTree::Ptr kdtree(new pcl::search::KdTree);

       kdtree->setInputCloud(cloud); // 设置要搜索的点云,建立KDTree

       std::vector indices; // 存储查询近邻点索引

       std::vector distances; // 存储近邻点对应距离的平方

       PointT point = cloud->points[0]; // 初始化一个查询点

      

       // 查询距point最近的k个点

       int k = 10;

       int size = kdtree->nearestKSearch(point, k, indices, distances);

       std::cout << "search point : " << size << std::endl;

       // 查询point半径为radius邻域球内的点

       double radius = 2.0;

       size = kdtree->radiusSearch(point, radius, indices, distances);

       std::cout << "search point : " << size << std::endl;

       system("pause");

       return 0;

}

03 Octree

1 点云压缩

??

2 使用八进制进行空间分区和搜索操作

3 无组织点云数据的空间变化检测

点云基础学习_第1张图片


通俗来说可以这样理解,假设A是一片人型点云,由人型点云创建了一个八叉树状结构,此时八叉树涵盖了A中所有点的位置,当第二片人形点云B出现,B和A的唯一区别就是B的左臂向上抬,此时利用上述方式,将B也放入之前A的树状结构,但是B的左臂上的点肯定不在之前A的树状结构中,因此会产生额外的树叶,这些额外的树叶内的点就是变化的点,即左臂的点。

05sample consensus 采样一致性算法

RANSAC算法假定我们要查看的所有数据均由内部值和异常值组成。可以用带有一组特定参数值的模型来解释离群值,而离群值在任何情况下都不适合该模型。其过程可以从数据中估计所选模型的最佳参数

RANSAC从样本中随机抽选出一个样本子集,使用最小方差估计算法对这个子集计算模型参数,然后计算所有样本与该模型的偏差,再使用一个预先设定好的阈值与偏差比较,当偏差小于阈值时,该样本点属于模型内样本点 ( inliers),或称内部点、局内点或内点,否则为模型外样本点(outliers),或称外部点、局外点或外点,记录下当前的 inliers 的个数,然后重复这一过程。每一次重复都记录当前最佳的模型参数,所谓最佳即是inliers的个数最多 ,此时对应的inliers个数为 best_ninliers 。 

但是RANSAC 有两个问题

  1. 首先在每次迭代中都要区分 inliers 和 outlieres,因此需要事先设定阈值,当模型具有明显的物理意义时,这个阈值还比较容易设定,但是若模型比较抽象时,阈值就不那么容易设定了。而且固定阈值不适用于样本动态变化的应用;
  2. 第二个问题是,RANSAC的迭代次数是运行期决定的,不能预知迭代的确切次数(当然迭代次数的范围是可以预测的)。除此之外, RANSAC 只能从一个特定数据集中估计一个模型,当两个(或者更多个)模型存在时,RANSAC 同时找到多个模型

find_argument函数:查找命令行中是否有输入某命令,没有的话返回-1,有的话返回其起始下标

//创建随机采样一致性对象

  pcl::SampleConsensusModelSphere::Ptr

    model_s(new pcl::SampleConsensusModelSphere (cloud));    //针对球模型的对象

  pcl::SampleConsensusModelPlane::Ptr

    model_p (new pcl::SampleConsensusModelPlane (cloud));   //针对平面模型的对象

  if(pcl::console::find_argument (argc, argv, "-f") >= 0)

  {  //根据命令行参数,来随机估算对应平面模型,并存储估计的局内点

    pcl::RandomSampleConsensus ransac (model_p);

    ransac.setDistanceThreshold (.01);    //与平面距离小于0.01 的点称为局内点考虑,注意局内点设置参数

    ransac.computeModel();                   //执行随机参数估计

    ransac.getInliers(inliers);                 //存储估计所得的局内点

  }

  else if (pcl::console::find_argument (argc, argv, "-sf") >= 0 )

  {

   //根据命令行参数  来随机估算对应的圆球模型,存储估计的内点

    pcl::RandomSampleConsensus ransac (model_s);

    ransac.setDistanceThreshold (.01);

    ransac.computeModel();

    ransac.getInliers(inliers);

  }

  // 复制估算模型的所有的局内点到final中

  pcl::copyPointCloud(*cloud, inliers, *final);

个人理解:采样一致性在实际中是当一个点云的点数过多时候,对其按照一个要求进行采样。比如当样本数据过多或者数据不一致时,进行统一的采样。目的是以一个统一的形式把数据输入送入网络。

06 range-imagess深度图像

在PCL 中深度图像与点云最主要的区别在于其近邻的检索方式的不同,并且可以互相转换。

深度图像经过坐标转换可以计算为点云数据;有规则及必要信息的点云数据可以反算为深度图像

从点云创建深度图 How to create a range image from a point cloud

相关函数

函数:通过pointCloud点云创建深度图

createFromPointCloud(pointCloud, angularResolution,,maxAngleWidth, maxAngleHeight,sensorPose, coordinate_frame, noiseLevel, minRange, borderSize)

pointCloud:被检测点云

angularResolution=1:邻近的像素点所对应的每个光束之间相差 1°

maxAngleWidth=360:进行模拟的距离传感器对周围的环境拥有一个完整的360°视角,无论任何数据集都推荐使用此设置,因为最终获取的深度图像将被裁剪到有空间物体存在的区域范围

maxAngleHeight=180: 当传感器后面没有可以观测的点时,设置一个水平视角为180°的激光扫描仪即可,因为需要观察距离传感器前面就可以了。

sensorPose: 定义了模拟深度图像获取传感器的6DOF(6自由度)位置,其原始值为横滚角roll、俯仰角 pitch、偏航角 yaw 都为 0

coordinate_frame: 设置为CAMERA_FRAME说明系统的X轴是向右的、Y轴是向下的、Z轴是向前的,另外参数值是LASER_FRAME,其X轴向前、Y轴向左、Z轴向上

noiseLevel=0: 是指使用一个归一化的 Z缓存区来创建深度图像,如果想让邻近点集都落在同一个像素单元,可以设置一个较高的值,例如 noiseLevel = 0.05 可以理解为深度距离值是通过查询点半径为 5cm 的圆内包含的点用来平均计算而得到的 。

minRange=0:如果设置>0则所有模拟器所在位置半径 minRange 内的邻近点都将被忽略,即为盲区。

borderSize=1:如果设置>0 ,在裁剪图像时,将在图像周围留下当前视点不可见点的边界 。

从深度图中提取边界 How to extract borders from range images

我们对三种不同类型的点感兴趣:

  1. obstacle border:对象边界(属于对象的最外面的可见点)
  2. shadow border:阴影边界(在背景中与遮挡物相邻的点)
  3. Veil points:遮蔽点集(障碍物边界和阴影边界之间的插值点

以下是一个典型的激光雷达获得的3D数据对应的点云图:

点云基础学习_第2张图片

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