pcl_common库包含大多数PCL库使用的公共数据结构和方法。核心数据结构包括PointCloud类和许多用于表示点、表面法线、RGB颜色值、特征描述符等的点类型。它还包含许多用于计算距离/范数、均值和协方差、角度转换、几何变换,等等。这个模块是不依赖其他模块的,所以是可以单独编译成功,单独编译出来可利用其中的数据结构自行开发,当然想单独提取出来编译时需要自行修改cmakeLists的,这里就不再赘述。
那么我们就按顺序来解释其中每个函数的作用,有必要的话,我会解释其理论并结合代码实践。
PCL_common的类:
(1) class pcl::BivariatePolynomialT< real >
这表示一个二元多项式,并为它提供了一些功能接口。
(2)class pcl::CentroidPoint< PointT >
一个泛型类,它计算给输入点云的质心。
这里我们用“重心”不仅表示3D点坐标的平均值,而且表示其他数据字段中的值的平均值。通用的computeNDCentroid()函数也实现了这种功能,但它是以“不智能”的方式实现的,也就是说,不管字段内数据的语义如何,它都只是对值进行平均。在某些情况下(例如,对于x,y,z,强度场),这种行为是合理的,但是在其他情况下(例如,rgb,rgba,rgbl(label带标签的)),这并不会导致有意义的结果。
这个类能够以一种“智能”的方式计算质心,即考虑字段内数据的含义。目前支持以下字段:
* XYZ (x, y, z) 计算每个字段的平均值
* Normal (normal_x, normal_y, normal_z) 对每个字段平均值,并将得到的归一化的向量。
* Curvature (curvature) 曲率的平均值
* RGB/RGBA (rgb or rgba) rgba每个通道的平均值
* Intensity (intensity) 强度平均值
* Label (label) 标签字段的平均值
举例子
CentroidPoint<pcl::PointXYZ> centroid; centroid.add (pcl::PointXYZ (1, 2, 3); centroid.add (pcl::PointXYZ (5, 6, 7); //这里是在centroid点集中加两个点 pcl::PointXYZ c1; centroid.get (c1); //直接使用get函数获取该点集的在每个字段的均值 // 得到的结果是: c1.x == 3, c1.y == 4, c1.z == 5 // 我们也可以申明一个不一样字段的点云来存储结果 pcl::PointXYZRGB c2; centroid.get (c2); // 其中x,y,z字段的结果还是: c2.x == 3, c2.y == 4, c2.z == 5, // 但是 c2.rgb 是不被触及的
(3)struct pcl::NdConcatenateFunctor< PointInT, PointOutT >
点云点集相加的辅助函数
在这里要特别申明一下点云库中点云的相加有两种方式:
-
比如:cloud_c = cloud_a;
cloud_c += cloud_b;//把cloud_a和cloud_b连接一起创建cloud_c 后输出
输出如下图:
-
字段相加就会使用到该辅助函数,那么输出结果如下:
(4)class pcl::FeatureHistogram
用于计算一些浮点数均值和方差的直方图类型。
GlobalDescriptorsPtr global_descriptor; global_descriptor = computeGlobalDescriptor (cloud, normals); pcl::visualization::PCLHistogramVisualizer hist_vis; hist_vis.addFeatureHistogram (*global_descriptor, 308, "Global descriptor");
(5)class pcl::GaussianKernel
高斯核类集合了所有使用高斯核计算、卷积、平滑、梯度计算图像的方法。
float* kernel_ptr_host; int kernel_size = 5; float sigma = 1.0; kernel_ptr_host = probability_processor_->CreateGaussianKernel(sigma, kernel_size);
(6)class pcl::PCA< PointT >
主成分分析(PCA)类。
通过对输入点云集中心点的协方差矩阵进行奇异值分解,提取主成分。pca计算后的可用数据有输入数据的平均值、特征值(降序)和相应的特征向量。
其他方法允许在特征空间中进行投影、从特征空间重构以及用新的数据更新特征空间(根据Matej Artec, Matjaz Jogan and Ales Leonardis: "Incremental PCA for On-line Visual Learning and Recognition”)。
pcl::PCA<pcl::PointXYZ> pca; pcl::PointXYZ projected, reconstructed; for(size_t i = 0; i < cloud.size(); i++) { pca.project (cloud[i], projected); pca.reconstruct (projected, reconstructed); }
(7)class pcl::PiecewiseLinearFunction
提供了返回有效分段线性函数的值的功能。
inline float PiecewiseLinearFunction::getValue(float point) const { float vector_pos = factor_*point + offset_; float floored_vector_pos = floor(vector_pos); float interpolation_size = vector_pos-floored_vector_pos; int data_point_before = (std::max)(0, (std::min)(int(data_points_.size())-2, int(lrint(floored_vector_pos)))); //cout << "Interpolating between "<<data_point_before<<" and "<<data_point_before+1<<" with value " //<< interpolation_size<<" (vector size is "<<data_points_.size()<<").\n"; return data_points_[data_point_before]+interpolation_size*(data_points_[data_point_before+1]-data_points_[data_point_before]); }
(8)class pcl::PolynomialCalculationsT< real >
为多项式提供了一些功能,如寻找根或逼近二元多项式。
PolynomialCalculationsT<RealForPolynomial> polynomial_calculations; BivariatePolynomialT<RealForPolynomial> polynomial (2); float interest_value2 = interest_image_[index2]; sample_points.push_back (Eigen::Vector3d (x2-keypoint_x_int, y2-keypoint_y_int, interest_value2)); polynomial_calculations.bivariatePolynomialApproximation (sample_points, 2, polynomial)
(9)class pcl::PosesFromMatches
基于点对应的关系计算他们之间的三维空间变换
(10)class pcl::StopWatch
一个用于计时的秒表。
// Time measurements pcl::StopWatch sw; pcl::StopWatch sw_total; double t_select = 0.; double t_build = 0.; double t_nn_search = 0.; double t_calc_trafo = 0.; .... sw.reset (); ... t_select = sw.getTime (); sw.reset (); kd_tree_->setInputCloud (cloud_model_selected); t_build = sw.getTime (); ... t_nn_search += sw.getTime ();
(11)class pcl::ScopeTime
测量作用在作用域中的时间。
要使用这个类,例如测量函数中所花费的时间,只需在函数的开头创建一个实例。例子
{ pcl::ScopeTime t1 ("calculation"); // ... perform calculation here }
(12)class pcl::EventFrequency
一个辅助类来测量某个事件的频率。
(13)class pcl::TimeTrigger
定时调用回调函数的计时器类。
(14)class pcl::TransformationFromCorrespondences
基于对应的3D点计算变换。
pcl::TransformationFromCorrespondences transformation_from_correspondeces; transformation_from_correspondeces.reset (); transformation_from_correspondeces.add (corr1, point1); transformation_from_correspondeces.add (corr2, point2); transformation_from_correspondeces.add (corr3, point3); transformation_from_correspondeces.add (corr4, point4); transformation_from_correspondeces.add (corr5, point5); transformation_from_correspondeces.add (corr6, point6); transformation_from_correspondeces.add (corr7, point7); transformation_from_correspondeces.add (corr8, point8); ++counter_for_added_pose_estimates; PoseEstimate pose_estimate; pose_estimate.transformation = transformation_from_correspondeces.getTransformation (); pose_estimate.score = 0.5f * (correspondence1.distance + correspondence2.distance); // TODO: base on the measured distance_errors? pose_estimate.correspondence_indices.push_back (correspondence1_idx); pose_estimate.correspondence_indices.push_back (correspondence2_idx); pose_estimates.push_back (pose_estimate);
(15)class pcl::VectorAverage< real, dimension >
计算给定权重的一组向量的加权平均和协方差矩阵的类
VectorAverage3f vector_average; float max_dist_squared=max_dist*max_dist, max_dist_reciprocal=1.0f/max_dist; bool still_in_range = true; for (int radius=1; still_in_range; ++radius) { int x2=x-radius-1, y2=y-radius; // Top left - 1 still_in_range = false; for (int i=0; i<8*radius; ++i) { if (i<=2*radius) ++x2; else if (i<=4*radius) ++y2; else if (i<=6*radius) --x2; else --y2; if (!isValid (x2, y2)) { continue; } getPoint (x2, y2, neighbor); float distance_squared = (neighbor-point).squaredNorm (); if (distance_squared > max_dist_squared) { continue; } still_in_range = true; float distance = std::sqrt (distance_squared), weight = distance*max_dist_reciprocal; vector_average.add (neighbor, weight); } }
(16)struct pcl::Correspondence
对应表示两个实体(例如,点、描述子等)之间的匹配。通过源点云与目标点云之间的距离来表示。
// Find Model-Scene Correspondences with KdTree // pcl::CorrespondencesPtr model_scene_corrs (new pcl::Correspondences ()); pcl::KdTreeFLANN<DescriptorType> match_search; match_search.setInputCloud (model_descriptors); // For each scene keypoint descriptor, find nearest neighbor into the model keypoints descriptor cloud and add it to the correspondences vector. for (size_t i = 0; i < scene_descriptors->size (); ++i) { std::vector<int> neigh_indices (1); std::vector<float> neigh_sqr_dists (1); if (!pcl_isfinite (scene_descriptors->at (i).descriptor[0])) //skipping NaNs { continue; } int found_neighs = match_search.nearestKSearch (scene_descriptors->at (i), 1, neigh_indices, neigh_sqr_dists); if(found_neighs == 1 && neigh_sqr_dists[0] < 0.25f) // add match only if the squared descriptor distance is less than 0.25 (SHOT descriptor distances are between 0 and 1 by design) { pcl::Correspondence corr (neigh_indices[0], static_cast<int> (i), neigh_sqr_dists[0]); model_scene_corrs->push_back (corr); } } std::cout << "Correspondences found: " << model_scene_corrs->size () << std::endl;
(17)struct pcl::PointCorrespondence3D
表示两个不同坐标系中的两个3D点之间的(可能的)对应关系(例如,来自特征匹配)
(18)struct pcl::PointCorrespondence6D
表示两个点之间的(可能的)对应关系(例如来自特征匹配),是一个6DOF变换。
这三个类是继承的关系。


(19)以下是点云库中已经定义好的点云的形式
struct pcl::PointXYZ
表示Euclidean xyz坐标的点集结构类型
struct pcl::Intensity
表示单通道图像灰度强度的点集结构类型
struct pcl::Intensity8u
一种表示单通道图像灰度强度的点集结构类型
struct pcl::Intensity32u
表示单通道图像灰度强度的点集结构类型
struct pcl::_PointXYZI
表示欧氏XYZ坐标的点集结构和强度值
struct pcl::PointXYZRGBA
表示欧氏XYZ坐标和RGBA颜色的点集结构类型
struct pcl::PointXYZRGB
表示欧氏XYZ坐标和RGB颜色的点集结构类型struct
pcl::PointXY
表示Euclidean xy坐标的二维点集结构类型
struct pcl::PointUV
表示像素图像坐标的2D点集结构类型
struct pcl::InterestPoint
表示具有欧几里德xyz坐标和兴趣值的点集结构类型
给个例子关于这个特殊的类型:
pcl::visualization::RangeImageVisualizer* pcl::visualization::RangeImageVisualizer::getInterestPointsWidget ( const pcl::RangeImage& range_image, const float* interest_image, float min_value, float max_value, const pcl::PointCloud<pcl::InterestPoint>& interest_points, const std::string& name) { RangeImageVisualizer* widget = new RangeImageVisualizer; widget->showFloatImage (interest_image, range_image.width, range_image.height, min_value, max_value); widget->setWindowTitle (name); for (unsigned int i=0; i<interest_points.points.size(); ++i) { const pcl::InterestPoint& interest_point = interest_points.points[i]; float image_x, image_y; range_image.getImagePoint (interest_point.x, interest_point.y, interest_point.z, image_x, image_y); widget->markPoint (static_cast<size_t> (image_x), static_cast<size_t> (image_y), green_color, red_color); } return widget; }
struct pcl::Normal
表示法向量坐标和曲面曲率估计的点集结构类型
struct pcl::Axis
用法向量坐标表示轴的点集结构
struct pcl::PointNormal
表示欧几里德xyz坐标的点集结构,连同法线坐标和表面曲率估计值
struct pcl::PointXYZRGBNormal
表示欧几里德xyz坐标和RGB颜色的点集结构,以及法线坐标和表面曲率估计.
struct pcl::PointXYZINormal
表示欧几里德xyz坐标,强度,连同法线坐标和表面曲率估计的点集结构类型。
struct pcl::PointXYZLNormal
表示欧几里得xyz坐标,一个标签,法线坐标和表面曲率估计的点集结构类型
struct pcl::PointWithRange
表示欧几里德XYZ坐标的点集结构,并连同的浮点数的深度信息
struct pcl::PointWithViewpoint
表示欧几里得xyz坐标的点集结构以及的视点的点集结构
struct pcl::MomentInvariants
表示三个矩是不变量的点集结构类型
struct pcl::PrincipalRadiiRSD
表示使用RSD计算的最小和最大表面半径(以米为单位)的点集结构类型
struct pcl::Boundary
表示点是否位于表面边界的点集结构
struct pcl::PrincipalCurvatures
表示主曲率及其幅值的点集结构
(20)以下是一些三维特征点描述子的点集结构,其中每个描述子都是一篇论文,希望有兴趣的小伙伴加入我们,每个人分析解释一种描述子的由来以及理论研究。
struct pcl::PFHSignature125
表示点云的特征直方图(PFH)的点集结构类型
struct pcl::PFHRGBSignature250
表示颜色特征点特征直方图的点结构(PFHGB)
struct pcl::PPFSignature
用于存储点对特征(PPF)值的点集结构
struct pcl::CPPFSignature
用于存储点对特征(CPPP)值的点集结构
struct pcl::PPFRGBSignature
用于存储点对颜色特征(PPFRGB)值的点集结构
struct pcl::NormalBasedSignature12
表示4-By3的特征矩阵的基于正常的签名的点结构
struct pcl::ShapeContext1980
表示形状上下文的点结构
struct pcl::UniqueShapeContext1960
表示唯一形状上下文的点结构
struct pcl::SHOT352
表示OrienTations直方图(SHOT)的通用标签形状的点集结构
struct pcl::SHOT1344
一种点结构,表示OrienTations直方图(SHOT)的通用签名-形状+颜色。
struct pcl::_ReferenceFrame
表示点的局部参照系的结构
struct pcl::FPFHSignature33
表示快速点特征直方图(FPFH)的点结构
struct pcl::VFHSignature308
表示视点特征直方图(VFH)的点结构
struct pcl::GRSDSignature21
表示全局半径的表面描述符(GRSD)的点结构。
struct pcl::BRISKSignature512
表示二进制鲁棒不变可缩放关键点(BRISK)的点结构。
struct pcl::ESFSignature640
表示形状函数集合的点结构(ESF)
struct pcl::GASDSignature512
表示全局对准的空间分布(GASD)形状描述符的点结构
struct pcl::GASDSignature984
表示全局对齐空间分布(GASD)形状和颜色描述符的点结构
struct pcl::GASDSignature7992
表示全局对齐空间分布(GASD)形状和颜色描述符的点结构
struct pcl::GFPFHSignature16
表示具有16个容器的GFPFH描述符的点结构。
struct pcl::Narf36
表示NARF描述符的点结构
struct pcl::BorderDescription
用于存储距离图像中的点位于障碍物和背景之间的边界上的结构
struct pcl::IntensityGradient
表示Xyz点云强度梯度的点结构
struct pcl::Histogram< N >
表示N-D直方图的点结构
struct pcl::PointWithScale
表示三维位置和尺度的点结构
struct pcl::PointSurfel
曲面,即表示欧几里德xyz坐标的点结构,连同法向坐标、RGBA颜色、半径、置信值和表面曲率估计。
struct pcl::PointDEM
表示数字高程图的点结构 Digital Elevation Map. ..
class pcl::PCLBase< PointT >
PCL的基类
struct pcl::GradientXY
表示欧氏XYZ坐标的点结构和强度值
对于以上描述子的具体解读,我们已经组织群友们,一起阅读,并写出自己的理解,希望大家一起能加入我们学习分享。
有兴趣的小伙伴可以关注微信公众号,加入QQ或者微信群,和大家一起交流分享吧