这次我们将使用pcl::ROPSEstimation这个类来导出点的特征。
下面是这个方法的特征提取方式。有一个网格和一个点集可以让我们来执行一些简单的操作。第一步,对于一个给定的兴趣点局部的表面将会被削平。局部表面包含了在半径内的点和三角形。对于给定的局部表面LRF将被计算。LRF是向量的3个组之一。真正重要的是使用那些具有旋转不变的向量。为了做到这一点,我们把感兴趣的点作为原点来做转换,再这之后我们旋转局部表面,以至于LRF向量关于Ox,Oy,Oz坐标轴对称。完成这些后,我们开始了特征导出。对于每个Ox,Oy,Oz坐标轴,我们会把这些这些坐标轴作为当前的坐标轴。
1.局部表面通过一个给定的角度在当前的坐标轴进行旋转。
2.把局部表面投影成3个平面XY,XZ和YZ.
3.对于每个投影分布矩阵,这个矩阵将展示怎么样把把点分到不同的容器里面。容器的数量代表了矩阵的维度和算法的参数。
4.每个分布矩阵的中心矩将会被计算。M11,M12,M21,M22,E。E是信息熵。
5.计算值将会组成子特征。
我们把上面这些步骤进行多次迭代。不同坐标轴的子特征将组成RoPS描述器。
下面是代码
我们首先要找到目标模型
points 包含点云
indices 点的下标
triangles包含了多边形
#include <pcl/features/rops_estimation.h> #include <pcl/io/pcd_io.h> int main (int argc, char** argv) { if (argc != 4) return (-1); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ()); if (pcl::io::loadPCDFile (argv[1], *cloud) == -1) return (-1); pcl::PointIndicesPtr indices = boost::shared_ptr <pcl::PointIndices> (new pcl::PointIndices ()); std::ifstream indices_file; indices_file.open (argv[2], std::ifstream::in); for (std::string line; std::getline (indices_file, line);) { std::istringstream in (line); unsigned int index = 0; in >> index; indices->indices.push_back (index - 1); } indices_file.close (); std::vector <pcl::Vertices> triangles; std::ifstream triangles_file; triangles_file.open (argv[3], std::ifstream::in); for (std::string line; std::getline (triangles_file, line);) { pcl::Vertices triangle; std::istringstream in (line); unsigned int vertex = 0; in >> vertex; triangle.vertices.push_back (vertex - 1); in >> vertex; triangle.vertices.push_back (vertex - 1); in >> vertex; triangle.vertices.push_back (vertex - 1); triangles.push_back (triangle); } float support_radius = 0.0285f; unsigned int number_of_partition_bins = 5; unsigned int number_of_rotations = 3; pcl::search::KdTree<pcl::PointXYZ>::Ptr search_method (new pcl::search::KdTree<pcl::PointXYZ>); search_method->setInputCloud (cloud); pcl::ROPSEstimation <pcl::PointXYZ, pcl::Histogram <135> > feature_estimator; feature_estimator.setSearchMethod (search_method); feature_estimator.setSearchSurface (cloud); feature_estimator.setInputCloud (cloud); feature_estimator.setIndices (indices); feature_estimator.setTriangles (triangles); feature_estimator.setRadiusSearch (support_radius); feature_estimator.setNumberOfPartitionBins (number_of_partition_bins); feature_estimator.setNumberOfRotations (number_of_rotations); feature_estimator.setSupportRadius (support_radius); pcl::PointCloud<pcl::Histogram <135> >::Ptr histograms (new pcl::PointCloud <pcl::Histogram <135> > ()); feature_estimator.compute (*histograms); return (0); }
上面是指定下标点的RoPS特征计算的地方
std::vector <pcl::Vertices> triangles; std::ifstream triangles_file; triangles_file.open (argv[3], std::ifstream::in); for (std::string line; std::getline (triangles_file, line);) { pcl::Vertices triangle; std::istringstream in (line); unsigned int vertex = 0; in >> vertex; triangle.vertices.push_back (vertex - 1); in >> vertex; triangle.vertices.push_back (vertex - 1); in >> vertex; triangle.vertices.push_back (vertex - 1); triangles.push_back (triangle); }
上面是加载关于多边形的信息的。你可以取代信息用下面的代码来进行三角划分,如果你只有点云没有网格图。
float support_radius = 0.0285f; unsigned int number_of_partition_bins = 5; unsigned int number_of_rotations = 3;
上面的这些代码定义了重要的算法参数,局部表面裁剪支持的半径,以及用于组成分布矩阵的容器的数量和旋转的次数。最后的参数将影响描述器的长度。
上面设置了搜索方法。
pcl::ROPSEstimation <pcl::PointXYZ, pcl::Histogram <135> > feature_estimator; feature_estimator.setSearchMethod (search_method); feature_estimator.setSearchSurface (cloud); feature_estimator.setInputCloud (cloud); feature_estimator.setIndices (indices); feature_estimator.setTriangles (triangles); feature_estimator.setRadiusSearch (support_radius); feature_estimator.setNumberOfPartitionBins (number_of_partition_bins); feature_estimator.setNumberOfRotations (number_of_rotations); feature_estimator.setSupportRadius (support_radius);
上面是实例化类的地方。它包含了两个参数
PointInT:输入点的类型
PointOutT:输出点的类型
最终我们需要进行特征计算
pcl::PointCloud<pcl::Histogram <135> >::Ptr histograms (new pcl::PointCloud <pcl::Histogram <135> > ()); feature_estimator.compute (*histograms);
然后运行
./rops_feature points.pcd indices.txt triangles.txt