参考资料:
https://github.com/Ewenwan/MVision/blob/master/PCL_APP/1_%E7%82%B9%E4%BA%91%E6%BB%A4%E6%B3%A2filter.md
点云库PCL各模块学习 · 语雀
各模块依赖关系:
模块:
common
pcl_common中主要是包含了PCL库常用的公共数据结构和方法,比如PointCloud的类和许多用于表示点,曲面,法向量,特征描述等点的类型,用于计算距离,均值以及协方差,角度转换以及几何变化的函数。
kdtree kd树
背景
特征点匹配:通过距离函数在高维矢量之间进行相似性检索的问题。针对如何快速而准确地找到查询点的近邻,现在提出了很多高维空间索引结构和近似查询的算法,k-d树就是其中一种
索引结构中相似性查询有两种基本的方式:一种是范围查询(range searches),另一种是K近邻查询(K-neighbor searches)
- 范围查询(range searches):给定查询点和查询距离的阈值,从数据集中找出所有与查询点距离小于阈值的数据
- K近邻查询(K-neighbor searches):给定查询点及正整数K,从数据集中找到距离查询点最近的K个数据,当K=1时,就是最近邻查询(nearest neighbor searches)。
特征匹配算子大致可以分为两类。
- 一类是线性扫描法,即将数据集中的点与查询点逐一进行距离比较,也就是穷举,缺点很明显,搜索效率较低
- 第二类是建立数据索引,然后再进行快速匹配。因为实际数据一般都会呈现出簇状的聚类形态,通过设计有效的索引结构可以大大加快检索的速度。
-
- 索引树属于第二类,其基本思想就是对搜索空间进行层次划分。
-
-
- 根据划分的空间是否有混叠可以分为Clipping和Overlapping两种
- 前者划分空间没有重叠,其代表就是k-d树;
- 后者划分空间相互有交叠,其代表为R树。
-
kd 树的结构
kd树是一个二叉树结构,它的每一个节点记载了【特征坐标,切分轴,左指针,右枝指针】。
kd 树上的 kNN 算法
图形示例
一层对比x坐标,一层对比y坐标
这个节点只有一个子枝,就不需要对比了。由此找到了最底部的节点 (−4.6,−10.55)。
在二维图上是
此时我们执行 (二)。将当前结点标记为访问过,并记录下 L=[(−4.6,−10.55)]。啊,访问过的节点就在二叉树上显示为被划掉的好了。
然后执行 (三),嗯,不是最顶端节点。好,执行 (a),我爬。上面的是 (−6.88,−5.4)。
octree 八叉树
建立空间索引在点云数据处理中有着广泛的应用,常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构,比较有代表性的包括BSP树,KD树,KDB树,R树,四叉树,八叉树等索引结构,而这些结构中,KD树和八叉树使用比较广泛
八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。
百度百科释义:
八叉树(Octree)的定义是:若不为空树的话,树中任一节点的子节点恰好只会有八个,或零个,也就是子节点不会有0与8以外的数目。那么,这要用来做什么?想象一个立方体, 我们最少可以切成多少个相同等分的小立方体?答案就是8个。再想象我们有一个房间,房间里某个角落藏着一枚金币,我们想很快的把金币找出来,聪明的你会怎 么做?我们可以把房间当成一个立方体,先切成八个小立方体,然后排除掉没有放任何东西的小立方体,再把有可能藏金币的小立方体继续切八等份….如此下去, 平均在Log8(房间内的所有物品数)的时间内就可找到金币。因此,八叉树就是用在3D空间中的场景管理,可以很快地知道物体在3D场景中的位置,或侦测 与其它物体是否有碰撞以及是否在可视范围内。
实现八叉树的原理
(1). 设定最大递归深度。
(2). 找出场景的最大尺寸,并以此尺寸建立第一个立方体。
(3). 依序将单位元元素丢入能被包含且没有子节点的立方体。
(4). 若没达到最大递归深度,就进行细分八等份,再将该立方体所装的单位元元素全部分担给八个子立方体。
(5). 若发现子立方体所分配到的单位元元素数量不为零且跟父立方体是一样的,则该子立方体停止细分,因为跟据空间分割理论,细分的空间所得到的分配必定较少,若是一样数目,则再怎么切数目还是一样,会造成无穷切割的情形。
(6). 重复3,直到达到最大递归深度。
八叉树的逻辑结构如下:
假设要表示的形体V可以放在一个充分大的正方体C内,C的边长为2n,形体V=C,它的八叉树可以用以下的递归方法来定义:八 叉树的每个节点与C的一个子立方体对应,
树根与C本身相对应,如果V=C,那么V的八叉树仅有树根,如果V≠C,则将C等分为八个子立方体,每个子立方体 与树根的一个子节点相对应。只要某个子立方体不是完
全空白或完全为V所占据,就要被八等分,从而对应的节点也就有了八个子节点。这样的递 归判断、分割一直要进行到节点所对应的立方体或是完全空白,或是完全为V占
据,或是其大小已是预先定义的体素大小,并且对它与V之交作一定的“舍入”,使 体素或认为是空白的,或认为是V占据的。
背景:
- 通过雷达、激光扫描、立体摄像机等三维测量设备获取的点云数据,具有数据量大、分布不均匀等特点。作为三维领域中一个重要的数据来源,点云数据主要是表征目标表面的海量点集合,并不具备传统网格数据的集合拓扑信息。所以点云数据处理中最为核心的问题就是建立离散点间的拓扑关系,实现基于邻域关系的快速查找。
- 建立空间索引在点云数据处理中有着广泛的应用,常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构
-
- 比较有代表性的包括BSP树,KD树,KDB树,R树,四叉树,八叉树等索引结构
- 而这些结构中,KD树和八叉树使用比较广泛
这个带颜色的示意图很清楚的解释了八叉树的结构。每一个小立方体(voxel)都是一个子节点。子节点可以被继续划分。
八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。
- 一般中心点作为节点的分叉中心。
- 八叉树若不为空树的话,树中任一节点的子节点恰好只会有八个,或零个,也就是子节点不会有0与8以外的数目。
- 分割一直要进行到节点所对应的立方体或是完全空白,或是完全为V占据,或是其大小已是预先定义的体素大小,并且对它与V之交作一定的“舍入”,使体素或认为是空白的,或认为是V占据的。
应用实例:
1. 点云压缩
点云由海量的数据集组成,这些数据集通过距离 颜色 法线 等附加信息来描述空间的三维点,此外,点云还能易非常高的速度被创建出来,因此需要占用相当大的存储资源,一旦点云需要存储或者通过速率受限制的通信信道进行传输,提供针对这种数据的压缩方法就变得十分有用,PCL 提供了点云的压缩功能,它允许编码压缩所有类型的点云,
2 使用八进制进行空间分区和搜索操作
3 无组织点云数据的空间变化检测
search 搜索(基于octree和kdtree)
1. K近邻搜索(K nearest neighbor search)
求一个点的最紧邻点:
在pcl中可以通过对点云建立 kdtree ,然后求一个点的 最紧邻点
2. 体素近邻搜索(Neighbors within voxel search)
3. 半径内近邻搜索(Neighbors within radius search)
Sample Consensus 抽样一致性模块
广泛的使用各种不同的采样一致性参数估计算法用于排除错误的样本,样本不同对应的应用不同,例如剔除错误的配准点对,分割出处在模型上的点集
PCL 中以随机采样一致性算法( RANSAC) 为核心,实现了五种类似于RANSAC的随机参数估计算法,例如随机采样一致性估计(RANSAC ) 、最大似然一致性估计 (MLESAC ) 、最小中值方差一致性估计 ( LMEDS )等,所有的估计参数算法都符合一致性准则。
- 利用RANSAC可以实现点云分割,目前 PCL 中支持的几何模型分割有 空间平面、直线、二维或三维圆、圆球、锥体等 。 RANSAC的另一应用就是点云的配准对的剔除。
在PCL中设计的采样一致性算法的应用主要就是对点云进行分割,根据设定的不同的几个模型,估计对应的几何参数模型的参数,在一定容许的范围内分割出在模型上的点云。
range-images 深度图像
区分点云与深度图本质的区别
1.深度图像(Depth Images)也被称为距离影像(Range Image),是指将从图像采集器到场景中各点的距离值作为像素值的图像,它直接反应了景物可见表面的几何形状。获取方法有:激光雷达深度成像法、计算机立体视觉成像、坐标测量机法、莫尔条纹法、结构光法。
2.点云:当一束激光照射到物体表面时,所反射的激光会携带方位、距离等信息。若将激光束按照某种轨迹进行扫描,便会边扫描边记录到反射的激光点信息,由 于扫描极为精细,则能够得到大量的激光点,因而就可形成激光点云。点云格式有*.las ;*.pcd; *.txt等。
在PCL 中深度图像与点云最主要的区别在于其近邻的检索方式的不同,并且可以互相转换。
深度图像经过坐标转换可以计算为点云数据;有规则及必要信息的点云数据可以反算为深度图像
rangeimage是来自传感器一个特定角度拍摄的一个三维场景获取的有规则的有焦距等基本信息的深度图。
深度图像的像素值代表从传感器到物体的距离或者深度值
tracking 目标检测和追踪
Code注释和分析(3D-LIDAR Multi Object Tracking) · 语雀
IO 数据输入输出,保存读取pcd
从PCD文件写入和读取点云数据、拼接点云
filters 滤波/降采样
点云滤波,顾名思义,就是滤掉噪声。原始采集的点云数据往往包含大量散列点、孤立点,
在获取点云数据时 ,由于设备精度,操作者经验环境因素带来的影响,以及电磁波的衍射特性,
被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中讲不可避免的出现一些噪声。
在点云处理流程中滤波处理作为预处理的第一步,对后续的影响比较大,只有在滤波预处理中
将噪声点 ,离群点,孔洞,数据压缩等按照后续处理定制,
才能够更好的进行配准,特征提取,曲面重建,可视化等后续应用处理.
其类似于信号处理中的滤波,
但实现手段却和信号处理不一样,主要有以下几方面原因:
1. 点云不是函数,无法建立横纵坐标之间的关系
2. 点云在空间中是离散的,不像图像信号有明显的定义域
3. 点云在空间中分布广泛,建立点与点之间的关系较为困难
4. 点云滤波依赖于集合信息而非数值信息
点云滤波方法主要有:
1. 直通滤波器 pcl::PassThrough<pcl::PointXYZ> pass
2. 体素格滤波器 pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
3. 统计滤波器 pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
4. 半径滤波器 pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
5. 双边滤波 pcl::BilateralFilter<pcl::PointXYZ> bf;
该类的实现利用的并非XYZ字段的数据进行,
而是利用强度数据进行双边滤波算法的实现,
所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,
双边滤波算法是通过取临近采样点和加权平均来修正当前采样点的位置,
从而达到滤波效果,同时也会有选择剔除与当前采样点“差异”太大的相邻采样点,从而保持原特征的目的
6. 高斯滤波 pcl::filters::GaussianKernel< PointInT, PointOutT >
是基于高斯核的卷积滤波实现 高斯滤波相当于一个具有平滑性能的低通滤波器
7. 立方体滤波 pcl::CropBox< PointT>
过滤掉在用户给定立方体内的点云数据
8. 封闭曲面滤波 pcl::CropHull< PointT>
过滤在给定三维封闭曲面或二维封闭多边形内部或外部的点云数据
9. 空间剪裁:
pcl::Clipper3D<pcl::PointXYZ>
pcl::BoxClipper3D<pcl::PointXYZ>
pcl::CropBox<pcl::PointXYZ>
pcl::CropHull<pcl::PointXYZ> 剪裁并形成封闭曲面
10. 卷积滤波:实现将两个函数通过数学运算产生第三个函数,可以设定不同的卷积核
pcl::filters::Convolution<PointIn, PointOut>
pcl::filters::ConvolvingKernel<PointInT, PointOutT>
11. 随机采样一致滤波等,通常组合使用完成任务。
PCL中总结了几种需要进行点云滤波处理情况,这几种情况分别如下:
(1) 点云数据密度不规则需要平滑
(2) 因为遮挡等问题造成离群点需要去除
(3) 大量数据需要下采样
(4) 噪声数据需要去除
对应的方案如下:
(1) 按照给定的规则限制过滤去除点
(2) 通过常用滤波算法修改点的部分属性
(3) 对数据进行下采样
features 特征
3D点云特征描述与提取是点云信息处理中的最基础也是最关键的一部分,
点云的识别、分割、重采样、配准、曲面重建等处理大部分算法,都严重依赖特征描述与提取的结果。
从尺度上来分,一般分为局部特征描述和全局特征描述。PCL/OpenNI tutorial 4: 3D object recognition (descriptors) - robotica.unileon.es有各种描述子较为详细的介绍。 下面给出常用的PFH、FPFH、SHOT、RoPS使用实例。
surface 表面
基本概念
曲面重建技术在逆向工程、数据可视化、机器视觉、虚拟现实、医疗技术等领域中得到了广泛的应用 。 例如,在汽车、航空等工业领域中,复杂外形产品的设计仍需要根据手工模型,采用逆向工程的手段建立产品的数字化模型,根据测量数据建立人体以及骨骼和器官的计算机模型,在医学、定制生产等方面都有重要意义 。
除了上述传统的行业,随着新兴的廉价 RGBD 获取设备在数字娱乐行业的病毒式扩展,使得更多人开始使用点云来处理对象并进行工程应用 。
根据重建曲面和数据点云之间的关系,可将曲面重建分为两大类:插值法和逼近法
- 插值法得到的重建曲面完全通过原始数据点
- 逼近法是用分片线性曲面或其他形式的曲面来逼近原始数据点,从而使得得到的重建曲面是原始点集的一个逼近曲面。
segmentation 分割(聚类)
介绍:
点云分割是根据空间,几何和纹理等特征对点云进行划分,使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提,例如逆向工作,CAD领域对零件的不同扫描表面进行分割,然后才能更好的进行空洞修复曲面重建,特征描述和提取,进而进行基于3D内容的检索,组合重用等。
官方tutorials
- Plane model segmentation 平面分割done
- Cylinder model segmentation 圆柱体分割done
- Euclidean Cluster Extraction 欧几里得簇提取done欧式聚类提取
- Region growing segmentation 区域增长细分
- Color-based region growing segmentation 基于颜色的区域增长分割
- Min-Cut Based Segmentation基于最小剪切的分割
- Conditional Euclidean Clustering 条件欧几里得聚类
- Difference of Normals Based Segmentation 基于法线的分割差异
- Clustering of Pointclouds into Supervoxels - Theoretical primer 点云聚集成超级体素-理论底漆
- Identifying ground returns using ProgressiveMorphologicalFilter segmentation 使用ProgressiveMorphologicalFilter细分识别地面收益
- Filtering a PointCloud using ModelOutlierRemoval 使用ModelOutlierRemoval过滤PointCloud
欧式聚类ConditionEuclideanClustering
一、算法概述
pcl::ConditionEuclideanClustering实现了点云的条件欧式聚类分割,与其他分割方法不同的是该方法的聚类约束条件(欧式距离、平滑度、RGB颜色等)可以由用户自己定义,即当搜索到一个近邻点时,用户可以自定义该邻域点是否合并到当前聚类的条件。
recognition 识别
基于对应分组的三维物体识别3D Object Recognition based on Correspondence Grouping
本教程旨在解释如何基于pcl_recognition模块执行3D对象识别。 具体来说,它解释了如何使用对应分组算法,以便将在3D描述符匹配阶段之后获得的点对点对应集合聚类到当前场景中存在的模型实例中。 对于表示场景中可能的模型实例的每个聚类,对应分组算法还输出识别当前场景中该模型的6DOF姿态估计的变换矩阵。
该算法输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等.
registration 配准
点云配准概念
由于三维扫描仪设备受到测量方式和被测物体形状的条件限制,一次扫描往往只能获取到局部的点云信息,进而需要进行多次扫描,然后每次扫描时得到的点云都有独立的坐标系,不可以直接进行拼接。
在逆向工程、计算机视觉、文物数字化等领域中,由于点云的不完整、旋转错位、平移错位等,使得要得到完整点云就需要对多个局部点云进行配准。
为了得到被测物体的完整数据模型,需要确定一个合适的坐标变换 ,将从各个视角得到的点集合并到一个统一的坐标系下形成一个完整的数据点云,然后就可以方便地进行可视化等操作,这就是点云数据的配准。
粗配准
粗配准是指在点云相对位姿完全未知的情况下对点云进行配准,找到一个可以让两块点云相对近似的旋转平移变换矩阵,进而将待配准点云数据转换到统一的坐标系内,可以为精配准提供良好的初始值。常见粗配准算法:
- 基于特征匹配(PFH)的配准算法:
-
- SAC-IA 采样一致性初始配准算法(Sample Consensus Initial Alignment)PCL库已实现,基于FPFH
- 基于穷举搜索的配准算法:
-
- 4PCS 四点一致集配准算法(4-Point Congruent Set)
- Super4PCS
精配准
精配准是指在粗配准的基础上,让点云之间的空间位置差异最小化,得到一个更加精准的旋转平移变换矩阵。该算法的运行速度以及向全局最优化的收敛性却在很大程度上依赖于给定的初始变换估计以及在迭代过程中对应关系的确立。所以需要各种粗配准技术为ICP算法提供较好的位置,在迭代过程中确立正确对应点集能避免迭代陷入局部极值,决定了算法的收敛速度和最终的配准精度。最常见的精配准算法是ICP及其变种。
- ICP 迭代最近点算法(Iterative Cloest Point)
迭代最近点算法(ICP)算法是Lidar SLAM中常用的点云配准方法,可以求解两组点云之间的相对位姿
-
- GICP
- NICP
- MBICP
- NDT 正态分布变换算法(Normal Distributions Transform)
其他配准:
- 依赖平台设备:将被测物体放在平台上,利用控制器对平台进行控制,使之按照指定角度转动,通过多次测量可以得到不同视角下的点云,由于提前获知了距离及角度信息,则可以直接对所有点云进行配准。
- 辅助标志点:通过在被测物体表面粘贴标签,将这些标签作为标志点,对多次测量得到的点云数据进行配准时,对这些有显著特征的标签进行识别配准,代替了对整体点云的配准,提高效率,精确度。
PCL实现的配准算法
上图中给出了示例,使用倾斜的2D激光设备获取了六个独立数据集。由于每个单独的扫描仅代表周围世界的一小部分,因此必须找到将它们配准在一起的方法,从而创建完整的点云模型,如下图所示。
visualization 可视化
class pcl::visualization::CloudViewer
类CloudViewer实现创建点云可视化的窗口,以及相关的可视化功能
keypoints 关键点(range_image.):
关键点也称为兴趣点,它是2D图像或是3D点云或者曲面模型上,
可以通过定义检测标准来获取的具有稳定性,区别性的点集。
关键点的数量相比于原始点云或图像的数据量减小很多,与局部特征描述子结合在一起,
组成 关键点描述子 常用来形成原始数据的表示,而且不失代表性和描述性,
常见的三维点云关键点提取算法有一下几种:
ISS3D、
Harris3D、
NARF、
SIFT3D
这些算法在PCL库中都有实现,其中NARF算法是博主见过用的比较多的。
关键点检测往往需要和特征提取联合在一起,关键点检测的一个重要性质就是旋转不变性,
也就是说,物体旋转后还能够检测出对应的关键点。
PCL中keypoints模块及类的介绍:
(1)class pcl::Keypoint<PointInT,PointOutT> 类keypoint是所有关键点检测相关类的基类,
定义基本接口,具体实现由子类来完成,
其继承关系时下图:
pcl::PCLBase<PointInT>
|
|___-> pcl::Keypoint<PointInT,PointOutT>
|
|
|
|___->pcl::AgastKeypoint2DBase<PointInT,PointOutT, pcl::common::IntensityFieldAccessor<PointInT >>
->pcl::AgastKeypoint2DBase<PointInT,PointOutT, IntensityT >
->pcl::BriskKeypoint2D<PointInT,PointOutT, IntensityT >
->pcl::HarrisKeypoint2D<PointInT,PointOutT, IntensityT >
->pcl::HarrisKeypoint3D<PointInT,PointOutT, IntensityT >
->pcl::HarrisKeypoint6D<PointInT,PointOutT, IntensityT >
->pcl::ISSKeypoint3D<PointInT,PointOutT, IntensityT >
->pcl::SIFTKeypoint<PointInT,PointOutT >
->pcl::SUSANKeypoint<PointInT,PointOutT, NormalT, IntensityT >
->pcl::TrajkovicKeypoint2D<PointInT,PointOutT, IntensityT >
->pcl::TrajkovicKeypoint3D<PointInT,PointOutT, IntensityT >
方法:
virtual void setSearchSurface (const PointCloudInConstPtr &cloud)
设置搜索时所用搜索点云,cloud为指向点云对象的指针引用
void setSearchMethod (const KdTreePtr &tree)
设置内部算法实现时所用的搜索对象,tree为指向kdtree或者octree对应的指针
void setKSearch (int k)
设置K近邻搜索时所用的K参数
void setRadiusSearch (double radius)
设置半径搜索的半径的参数
int searchForNeighbors (int index, double parameter, std::vector< int > &indices, std::vector< float > &distances) const
采用setSearchMethod设置搜索对象,以及setSearchSurface设置搜索点云,进行近邻搜索,返回近邻在点云中的索引向量,
indices以及对应的距离向量distance其中为查询点的索引,parameter为搜索时所用的参数半径或者K
Harris 算法
其思想及数学推导大致如下:
1.在图像中取一个窗 w (矩形窗,高斯窗,XX窗,各种窗,
某师姐要改标定算法不就可以从选Harris的窗开始做起么)
2.获得在该窗下的灰度 I
3.移动该窗,则灰度会发生变化,平坦区域灰度变化不大,
边缘区域沿边缘方向灰度变化剧烈,角点处各个方向灰度变化均剧烈
4.依据3中条件选出角点
1.两个特征值都很大==========>角点(两个响应方向)
2.一个特征值很大,一个很小===>边缘(只有一个响应方向)
3.两个特征值都小============>平原地区(响应都很微弱)
---------------------------------------------------------------------------
来自点云的降维打击
图像的Harris角点算子将图像的关键点定义为角点。角点也就是物体边缘的交点,harris算子利用角点在两个方向的灰度协方差矩阵响应都很大,来定义角点。既然关键点在二维图像中已经被成功定义且使用了,看来在三维点云中可以沿用二维图像的定义...不过今天要讲的是另外一种思路,简单粗暴,直接把三维的点云投射成二维的图像不就好了。这种投射方法叫做range_image.
3DHarris 方块体内点数量变化确定角点
在2DHarris里,我们使用了 图像梯度构成的 协方差矩阵。
图像梯度。。。嗯。。。。每个像素点都有一个梯度,
在一阶信息量的情况下描述了两个相邻像素的关系。显然这个思想可以轻易的移植到点云上来。
想象一下,如果在 点云中存在一点p
1、在p上建立一个局部坐标系:z方向是法线方向,x,y方向和z垂直。
2、在p上建立一个小正方体,不要太大,大概像材料力学分析应力那种就行
3、假设点云的密度是相同的,点云是一层蒙皮,不是实心的。
a、如果小正方体沿z方向移动,那小正方体里的点云数量应该不变
b、如果小正方体位于边缘上,则沿边缘移动,点云数量几乎不变,沿垂直边缘方向移动,点云数量改
c、如果小正方体位于角点上,则有两个方向都会大幅改变点云数量
如果由法向量x,y,z构成协方差矩阵,那么它应该是一个对称矩阵。
而且特征向量有一个方向是法线方向,另外两个方向和法线垂直。
那么直接用协方差矩阵替换掉图像里的M矩阵,就得到了点云的Harris算法。
其中,半径r可以用来控制角点的规模
r小,则对应的角点越尖锐(对噪声更敏感)
r大,则可能在平缓的区域也检测出角点
----------------------------------------------------------------------
NARF
参考
1. 边缘提取
对点云而言,场景的边缘代表前景物体和背景物体的分界线。
所以,点云的边缘又分为三种:
前景边缘,背景边缘,阴影边缘。
三维点云的边缘有个很重要的特征,
就是点a 和点b 如果在 rangImage 上是相邻的,然而在三维距离上却很远,那么多半这里就有边缘。
由于三维点云的规模和稀疏性,“很远”这个概念很难描述清楚。
到底多远算远?这里引入一个横向的比较是合适的。这种比较方法可以自适应点云的稀疏性。
所谓的横向比较就是和 某点周围的点相比较。 这个周围有多大?不管多大,
反正就是在某点pi的rangeImage 上取一个方窗。
假设像素边长为s. 那么一共就取了s^2个点。
接下来分三种情况来讨论所谓的边缘:
1.这个点在某个平面上,边长为 s 的方窗没有涉及到边缘
2.这个点恰好在某条边缘上,边长 s 的方窗一半在边缘左边,一半在右边
3.这个点恰好处于某个角点上,边长 s 的方窗可能只有 1/4 与 pi 处于同一个平面
如果将 pi 与不同点距离进行排序,得到一系列的距离,d0 表示与 pi 距离最近的点,显然是 pi 自己。
ds^2 是与pi 最远的点,这就有可能是跨越边缘的点了。
选择一个dm,作为与m同平面,但距离最远的点。
也就是说,如果d0~ds^2是一个连续递增的数列,那么dm可以取平均值。
如果这个数列存在某个阶跃跳动(可能会形成类似阶跃信号)
那么则发生阶跃的地方应该是有边缘存在,不妨取阶跃点为dm(距离较小的按个阶跃点)
原文并未如此表述此段落,原文取s=5, m=9 作为m点的一个合理估计。
-------------------------------------------------------------------------------
关键点提取
在提取关键点时,边缘应该作为一个重要的参考依据。
但一定不是唯一的依据。对于某个物体来说关键点应该是表达了某些特征的点,而不仅仅是边缘点。
所以在设计关键点提取算法时,需要考虑到以下一些因素:
1.边缘和曲面结构都要考虑进去,提取的过程考虑边缘以及物体表面变化信息;
2.关键点要能重复,在不同视角关键点可以被重复探测;
3.关键点最好落在比较稳定的区域,方便提取法线,关键点所在位置有足够的支持区域,可以计算描述子和进行唯一的估计法向量。
其对应的探测步骤如下:
(1) 遍历每个深度图像点,通过寻找在近邻区域有深度变化的位置进行边缘检测。
(2) 遍历每个深度图像点,根据近邻区域的表面变化决定一-测度表面变化的系数,及变化的主方向。
(3) 根据step(2)找到的主方向计算兴趣点,表征该方向和其他方向的不同,以及该处表面的变化情况,即该点有多稳定。
(4) 对兴趣值进行平滑滤波。
(5) 进行无最大值压缩找到的最终关键点,即为NARF关键点。
对于点云构成的曲面而言,某处的曲率无疑是一个非常重要的结构描述因素。
某点的曲率越大,则该点处曲面变化越剧烈。
在2D rangeImage 上,去 pi 点及其周边与之距离小于2deta的点,
进行PCA主成分分析。可以得到一个 主方向v,以及曲率值 lamda.
注意, v 必然是一个三维向量。
那么对于边缘点,可以取其 权重 w 为1 , v 为边缘方向。
对于其他点,取权重 w 为 1-(1-lamda)^3 , 方向为 v 在平面 p上的投影。
平面 p 垂直于 pi 与原点连线。
到此位置,每个点都有了两个量,一个权重,一个方向。
将权重与方向带入下列式子 I 就是某点 为特征点的可能性。
点云的特征点提取应该与后面的特征描述是松耦合的。
确实不得不承认,针对不同的点云:稀疏的,致密的,有序的,无序的,有遮挡的,高精测量的.......
设计不同的关键点提取算法也无可厚非。
总结出的关键点提取算法原则就是要尺度不变,鲁棒性好,至于是否一定要存在于平坦区域,我觉得并不一定。
不同的关键点提取算法可以和不同的特征描述算法进行组合,最终得到一个较好的效果。
如果非要把关键点提取算法和特征描述算法紧耦合,那势必会失去一部分灵活性。