网站做cpa推广引流,做ppt兼职网站有哪些,网络培训学校排名,武乡网站建设我这里不介绍pcl里面的类的命名规范#xff0c;及点的类型。为什么呢?pcl里面类的命名规范#xff0c;比较繁琐#xff0c;而且主要是针对要对pcl这个库要开源的人士#xff0c;而pcl里面的点的类型太多#xff0c;足够满足你的要求。所以我们要走一条具有中国特色的pcl主…我这里不介绍pcl里面的类的命名规范及点的类型。为什么呢?pcl里面类的命名规范比较繁琐而且主要是针对要对pcl这个库要开源的人士而pcl里面的点的类型太多足够满足你的要求。所以我们要走一条具有中国特色的pcl主义道路。
今天来介绍一下pcl里面的3D特征。
点是用来给一个给定区域来用笛卡尔坐标系x,y,z来进行描绘的一种方式。假定坐标系统的坐标原点没有变可能会有两个点比如p1和p2成为t1和t2但是它们的坐标是没变的。
比较这些点云是不稳定的,因为即使他们有相同的距离,但是它们可能采自不同的表面因此他们可能会代表不同的信息当把它们和表面上临近的点结合在一起的时候。这是因为很难确保现实世界里面的t1和t2没有变化。有一些获取点云的装置可能会获取一些额外的数据比如亮度(intensity)比如表面光滑度(翻译不一定对,surface remission value)和颜色等等但是以上的这些往往还是不能解决问题。 程序往往需要更好的特征或者是矩来区别几何表面。所以把3D点看成笛卡尔坐标系里面的一个单一的实体这个概念消失了我们引入了一个局部坐标系。文化是丰富多彩森罗万象的我们可以对同样的概念取很多的命名组合比如形状描述几何特征而在pcl里面是用点的特征来描述。 通过包含周边的点采样表面的几何特征可以被我们给推理或者捕获这将解决我们蛋疼的比较问题。理想情况下同一个或者相似表面上的点的特征是很相似的。那么怎么来找到一个比较好的描述点的特征呢当这个特征在下面这3个因素的影响下还能或得同样的表面特点的时候就是好的特征。
1.刚体转换。这包括了3D旋转与3D转换好的特征应该不会被此影响特征向量F(feature)不会改变。
2.不同的采样密度。总体来说一个局部的表面区域不管以高密度还是低密度的采样应该具有相同的特征向量。
3.噪声。这个不需要过多的解释。 总体来说pcl里面使用相似的方法来查询指定点的最近邻如使用kd-trees。下面是我们感兴趣的2个查询时需要的类型;
1.k。即查询时的最近邻的点的个数。
2.r。即搜索半径。 专业术语: term explanation Foo a class named Foo //英文里面很多随便取的类叫foo或bar类似张三李四 FooPtr a boost shared pointer to a class Foo,//boost共享指针 e.g., boost::shared_ptrFoo FooConstPtr a const boost shared pointer to a classFoo,//boost共享常量指针 e.g., const boost::shared_ptrconst Foo 怎么进行输入
pcl里面基本上所有的类都继承自pcl::PCLBase这个类所有pcl::Feature有两个方式来获取输入数据。
1.输入为整个点云数据集,setInputCloud(PointCloudConstPtr) 强制的
这将计算每一个输入点的特征。
2.输入为一个点云数据集的子集。setInputCloud(PointCloudPtr)和setIndices(IndicesConstPtr) 后面那个是可选的。
这将计算给定下标的输入点的特征。默认情况下下标是不会给的也就意味着每个点的特征都会被计算。
除此之外我们还可以通过别的调用如setSearchSurface(PointCloudConstPtr )来搜索表面上的点。 1.setIndices()false,setSearchSurface()false
这是pcl里面用的最多的不用任何的特征来排除点云即包含所有的点。
因为我们不希望根据是否有下标或者是否有表面来确定不同的点云的拷贝pcl内部创造了一系列的向量来指向整个数据集。
最左边的那幅图它先找到p1的最近邻再找p2的最近邻直到 把P这个点云里面的点穷尽。
2.setIndices()true,setSearchSurface()false
这只会计算在给定的下标向量里面的下标所对应点的特征比如p1是属于下标向量里面的,而p2不属于则只会计算p1附近的点的特征。
3.setIndices()false,setSearchSurface()true
只会计算潜在表面的最近邻的点的特征而不是整个点云。比如P和Q是两个点云然后把P作为要被搜索的表面(潜在的表面)则Q的每个元素(q1,q2)会在P中找到最近的几个点。
4.setIndices()true,setSearchSurfacetrue.这可能是最稀少的情况了因为这既要满足下标又要满足表面搜索。最后一幅图里面先通过下标把q2给排除然后再搜索q1在P里面的最近邻。 我们使用setSearchSurface()最多的例子是当我们有一个高密度的输入数据集的时候但是我们不想去计算里面所有点的特征在这个例子里面我们通过setSearchSurface()来解决这个问题而不是通过downsample(降低采样,往往通过pcl::VoxelGridT filter)或者keypoints(关键采样)。我们把downsampled/keypoints作为setInputCloud()的输入即是setSearchSurface()的原始数据集。 法线估计的一个例子
一旦决定了某个要查询点的周围的局部特征代表就可以捕获查询点的潜在表面的几何特征。在描述一个表面的几何特征的第一步是得到它在某个坐标下的方向因此要估计它的法线。下面的代码段将预测输入数据集的一系列表面法线。 #include pcl/point_types.h
#include pcl/features/normal_3d.h
{
pcl::PointCloudpcl::PointXYZ::Ptr cloud (new pcl::PointCloudpcl::PointXYZ);
... read, pass in or create a point cloud ...
// Create the normal estimation class, and pass the input dataset to it
pcl::NormalEstimationpcl::PointXYZ, pcl::Normal ne;
ne.setInputCloud (cloud);
// Create an empty kdtree representation, and pass it to the normal estimation object.
// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
pcl::search::KdTreepcl::PointXYZ::Ptr tree (new pcl::search::KdTreepcl::PointXYZ ());
ne.setSearchMethod (tree);
// Output datasets
pcl::PointCloudpcl::Normal::Ptr cloud_normals (new pcl::PointCloudpcl::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 the same size as the input cloud-points.size ()
}
下面的代码段将通过一个输入数据集预测一系列表面法线用另一个输入数据集评估最近邻。像前面提到的这是一个降低表面采样得到的数据集作为输入。
#include pcl/point_types.h
#include pcl/features/normal_3d.h
{
pcl::PointCloudpcl::PointXYZ::Ptr cloud (new pcl::PointCloudpcl::PointXYZ);
pcl::PointCloudpcl::PointXYZ::Ptr cloud_downsampled (new pcl::PointCloudpcl::PointXYZ);
... read, pass in or create a point cloud ...
... create a downsampled version of it ...
// Create the normal estimation class, and pass the input dataset to it
pcl::NormalEstimationpcl::PointXYZ, pcl::Normal ne;
ne.setInputCloud (cloud_downsampled);
// Pass the original data (before downsampling) as the search surface
ne.setSearchSurface (cloud);
// Create an empty kdtree representation, and pass it to the normal estimation object.
// Its content will be filled inside the object, based on the given surface dataset.
pcl::search::KdTreepcl::PointXYZ::Ptr tree (new pcl::search::KdTreepcl::PointXYZ ());
ne.setSearchMethod (tree);
// Output datasets
pcl::PointCloudpcl::Normal::Ptr cloud_normals (new pcl::PointCloudpcl::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 the same size as the input cloud_downsampled-points.size ()
}
还有通过下标来降低采样的下面这个例子
#include pcl/point_types.h
#include pcl/features/normal_3d.h
{
pcl::PointCloudpcl::PointXYZ::Ptr cloud (new pcl::PointCloudpcl::PointXYZ);
... read, pass in or create a point cloud ...
// Create a set of indices to be used. For simplicity, were going to be using the first 10% of the points in cloud
std::vectorint indices (floor (cloud-points.size () / 10));
for (size_t i 0; indices.size (); i) indices[i] i;
// Create the normal estimation class, and pass the input dataset to it
pcl::NormalEstimationpcl::PointXYZ, pcl::Normal ne;
ne.setInputCloud (cloud);
// Pass the indices
boost::shared_ptrstd::vectorint indicesptr (new std::vectorint (indices));
ne.setIndices (indicesptr);
// Create an empty kdtree representation, and pass it to the normal estimation object.
// Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
pcl::search::KdTreepcl::PointXYZ::Ptr tree (new pcl::search::KdTreepcl::PointXYZ ());
ne.setSearchMethod (tree);
// Output datasets
pcl::PointCloudpcl::Normal::Ptr cloud_normals (new pcl::PointCloudpcl::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 the same size as the input indicesptr-size ()
}