1.获得文件名的后缀
std::string file_extension = model_filename_.substr(model_filename_.find_last_of('.'));
2.STL文件转pointcloud 可用github上的fast-ppf里面的meshsampling 3.获得点云的最大x,y,z及平均值
pcl::PointXYZ minPt, maxPt, avgPt;
pcl::getMinMax3D(*model_sampling, minPt, maxPt);
avgPt.x = (minPt.x + maxPt.x) / 2;
avgPt.y = (minPt.y + maxPt.y) / 2;
avgPt.z = (minPt.z + maxPt.z) / 2;
4.从点云的正上中下共六个视角获得点云的放射点可以用可参考github上的fast-ppf里面的HPR。 5.点云显示更新
CustomVisualizer customViewer
customViewer.viewer->removeAllShapes();
customViewer.viewer->removeAllPointClouds();
customViewer.viewer->addPointCloud(model);
std::getchar();
6.计算点云pointcloud的中心点值,并进行点云中心化变换
Eigen::Vector3d sum_of_pos = Eigen::Vector3d::Zero();
for (const auto& p : *(model)) sum_of_pos += p.getVector3fMap().cast<double>();
Eigen::Matrix4d transform_centering = Eigen::Matrix4d::Identity();
transform_centering.topRightCorner<3, 1>() = -sum_of_pos / model->size();
pcl::transformPointCloud(*model, *model, transform_centering);
pcl::transformPointCloud(*model, *model, Eigen::Vector3f(0, 0, 0), Eigen::Quaternionf(0.7071, 0, -0.7071, 0));
7.计算点云分辨率
double computeCloudResolution (const pcl::PointCloud<PointType>::ConstPtr &cloud)
{
double res = 0.0;
int n_points = 0;
int nres;
std::vector<int> indices (2);
std::vector<float> sqr_distances (2);
pcl::search::KdTree<PointType> tree;
tree.setInputCloud (cloud);
for (size_t i = 0; i < cloud->size (); ++i)
{
if (! pcl_isfinite ((*cloud)[i].x))
{
continue;
}
nres = tree.nearestKSearch (i, 2, indices, sqr_distances);
if (nres == 2)
{
res += sqrt (sqr_distances[1]);
++n_points;
}
}
if (n_points != 0)
{
res /= n_points;
}
return res;
3 }
8.计算点云最大直径
double computeCloudDiameter(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled(new pcl::PointCloud<pcl::PointXYZ>());
pcl::VoxelGrid<PointXYZ> vg;
vg.setInputCloud(cloud);
vg.setLeafSize(0.005f, 0.005f, 0.005f);
vg.setDownsampleAllData(false);
vg.filter(*cloud_downsampled);
double diameter_sqr = 0;
for (size_t i = 0; i < cloud_downsampled->points.size(); i += 10)
{
for (size_t j = 0; j < cloud_downsampled->points.size(); j += 10)
{
if (i == j)
continue;
double distance_sqr = (cloud_downsampled->points[i].x - cloud_downsampled->points[j].x)*(cloud_downsampled->points[i].x - cloud_downsampled->points[j].x)
+ (cloud_downsampled->points[i].y - cloud_downsampled->points[j].y)*(cloud_downsampled->points[i].y - cloud_downsampled->points[j].y)
+ (cloud_downsampled->points[i].z - cloud_downsampled->points[j].z)*(cloud_downsampled->points[i].z - cloud_downsampled->points[j].z);
if (distance_sqr > diameter_sqr)
{
diameter_sqr = distance_sqr;
}
}
}
return sqrt(diameter_sqr);
}
9.计算法向量
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
ne.setInputCloud(model_keypoints);
ne.setSearchSurface(model);
ne.setNumberOfThreads(8);
ne.setSearchMethod(tree);
ne.setRadiusSearch(norm_rad);
ne.compute(*normals);
10. 11.pcl::concatenateFields(*model_keypoints, *normals, *model_keypoints_with_normals);把法向量加到点云数据里面,生产带有法向量的点云,即pcl::PointNormal类型, 背景有XYZ,还有normal
|