PCL点云库学习笔记(特征)
特征
一、概述
点特征是根据该点周围可用的信息来描述几何图案,在点周围选择的数据空间通常称为k邻域。两个最广泛使用的几何点特征是下表面的估计曲率和点法线,使用其k个最近点提供的信息来表征一个点。
为了有效地确定k,通常使用空间分解技术(例如八叉树或kD树)将输入数据集分成较小的块,然后在该空间中执行最近点搜索。 可以选择在p点附近的k个固定点,或者以点为中心的半径r的球体内的所有点。
计算点p处的表面法线和曲率变化的最简单方法是在k邻域内进行特征分解(即计算特征向量和特征值)。对应于最小特征值的特征向量将在点p处近似表面法线n,而表面曲率变化将从特征值估算为
二、特征模块在PCL中是如何工作的
通过setInputCloud(PointCloudConstPtr&)
给出整个点云的数据集,评估点云中每个点的特征;
通过setIndices(IndicesConstPtr&)
给定索引列表,具有索引的点才进行特征评估。 默认为false,不指定点,当setIndices()=true
时只对索引点进行评估;
通过setSearchSurface(PointCloudConstPtr&)
来指定要使用的点邻域集。指定要使用邻域点的表面;
当我们有一个非常密集的输入数据集时,只想要估计使用pcl_keypoints
方法发现的某些关键点,可以通过setInputCloud()
进行关键点输入,并将原始数据作为setSearchSurface()
传递。
代码将为输入数据集中的所有点估计一组表面法线。
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
{
//定义一个点集
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
//读取或创建点云数据
//创建法线估计类,把输入的点云数据传递给它
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud (cloud);//给定点云数据集
//创建一个空的kdtree,并将其传递给法线估计类
// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
ne.setSearchMethod (tree);
// 创建输出法线点云数据集
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
// Use all neighbors in a sphere of radius 3cm
ne.setRadiusSearch (0.03);
//计算发现特征
ne.compute (*cloud_normals);
// cloud_normals->points.size () should have the same size as the input cloud->points.size ()
}
以下为输入点云中的部分点的一组表面法线
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);//定义一组点云
... read, pass in or create a point cloud ...
// 创建一组要使用的索引。 索引的大小为输入点云中前10%的点
std::vector<int> indices (std::floor (cloud->points.size () / 10));
for (std::size_t i = 0; i < indices.size (); ++i) indices[i] = i;
// 创建普通的估计类,并将输入数据集传递给它
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud (cloud);
// 传递索引
pcl::shared_ptr<std::vector<int> > indicesptr (new std::vector<int> (indices));
ne.setIndices (indicesptr);
//创建一个空的kdtree表示形式,并将其传递给正常的估计对象
//它的内容将根据给定的输入数据集填充到对象内部(因为未提供其他搜索表面)。
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
ne.setSearchMethod (tree);
// Output datasets
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
// Use all neighbors in a sphere of radius 3cm
ne.setRadiusSearch (0.03);
// Compute the features
ne.compute (*cloud_normals);
// cloud_normals->points.size () should have