前言:
三维点云为三维欧式空间点的集合。对点云的形状描述若使用局部特征,则可分为两种:固定世界坐标系的局部描述和寻找局部主方向的局部描述,ROPS特征为寻找局部主方向的特征描述。
1.寻找主方向(对XYZ轴经过特定旋转)LFR:
<1>.计算法线特征:这一步是非常耗计算量的,若达到可以接受的法线精度,此过程几乎占据了 整个计算过程的50%;可选择的方法有 使用空间树索引建立近邻域,对近邻平面拟合,平面的参数方向既是法线一个方向。
<2>.进行多边形重建:利用贪婪投影的方法进行三角形重建,这个事一个调参数的过程,没有可以完全的方法。
参数有:
gp3.setSearchMethod treeNor);
gp3.setSearchRadius Gp3PolyParam.SearchRadius);// Set 最大搜索半径
gp3.setMu Gp3PolyParam.MuTypeValue);// Set typical values
gp3.setMaximumNearestNeighbors Gp3PolyParam.MaximumNearestNeighbors);
gp3.setMaximumSurfaceAngle Gp3PolyParam.MaximumSurfaceAngle); // 45 度
gp3.setMinimumAngle Gp3PolyParam.MinimumAngle); // 10 度
gp3.setMaximumAngle Gp3PolyParam.MaximumAngle); // 120 度
gp3.setNormalConsistency Gp3PolyParam.NormalConsistency);
<3>.计算整幅图像的ROPS特征:
查找PCL官网的tutoriales:http://pointclouds.org/documentation/tutorials/rops_feature.php。
#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);
}
