#include\x20 #include\x20<pcl/io/ply_io.h> #include\x20<pcl/point_types.h> #include\x20<pcl/visualization/pcl_visualizer.h> #include\x20<pcl/point_cloud.h> #include\x20<pcl/filters/filter.h> #include\x20<pcl/common/common.h> #include\x20<pcl/features/integral_image_normal.h> #include\x20<pcl/kdtree/kdtree_flann.h>

#include\x20 #include\x20

using\x20namespace\x20std; using\x20namespace\x20pcl;

struct\x20Edge\x20{ \x20\x20int\x20src, dst; \x20\x20float\x20weight; };

bool\x20cmp(Edge\x20a, Edge\x20b)\x20{ \x20\x20return\x20a.weight\x20<\x20b.weight; }

int\x20find(vector&\x20parent, int\x20i)\x20{ \x20\x20if\x20(parent[i]\x20==\x20-1)\x20{ \x20\x20\x20\x20return\x20i; \x20\x20} \x20\x20return\x20find(parent, parent[i]); }

void\x20unionSet(vector&\x20parent, int\x20x, int\x20y)\x20{ \x20\x20int\x20xset\x20=\x20find(parent, x); \x20\x20int\x20yset\x20=\x20find(parent, y); \x20\x20parent[xset]\x20=\x20yset; }

PointCloud::Ptr\x20readPointCloud(string\x20file_path)\x20{ \x20\x20PointCloud::Ptr\x20cloud(new\x20PointCloud); \x20\x20io::loadPLYFile(file_path, *cloud); \x20\x20vector indices; \x20\x20removeNaNFromPointCloud(*cloud, *cloud, indices); \x20\x20return\x20cloud; }

void\x20writePointCloud(string\x20file_name, PointCloud::Ptr\x20cloud)\x20{ \x20\x20io::savePLYFile(file_name, *cloud); }

void\x20skeletonPruning(PointCloud::Ptr\x20cloud, float\x20alpha)\x20{ \x20\x20PointCloud::Ptr\x20cloud_pruned(new\x20PointCloud); \x20\x20for\x20(int\x20i\x20=\x200; i\x20<\x20cloud->size(); i++)\x20{ \x20\x20\x20\x20PointXYZ\x20p1\x20=\x20cloud->points[i]; \x20\x20\x20\x20int\x20count\x20=\x200; \x20\x20\x20\x20for\x20(int\x20j\x20=\x20i\x20+\x201; j\x20<\x20cloud->size(); j++)\x20{ \x20\x20\x20\x20\x20\x20PointXYZ\x20p2\x20=\x20cloud->points[j]; \x20\x20\x20\x20\x20\x20float\x20dist\x20=\x20sqrt(pow(p1.x\x20-\x20p2.x, 2)\x20+\x20pow(p1.y\x20-\x20p2.y, 2)\x20+\x20pow(p1.z\x20-\x20p2.z, 2)); \x20\x20\x20\x20\x20\x20if\x20(dist\x20<\x20alpha)\x20{ \x20\x20\x20\x20\x20\x20\x20\x20count++; \x20\x20\x20\x20\x20\x20} \x20\x20\x20\x20} \x20\x20\x20\x20if\x20(count\x20>=\x20alpha)\x20{ \x20\x20\x20\x20\x20\x20cloud_pruned->push_back(p1); \x20\x20\x20\x20} \x20\x20} \x20\x20cloud\x20=\x20cloud_pruned; }

void\x20nodeClassification(PointCloud::Ptr\x20cloud)\x20{ \x20\x20vector parent(cloud->size(), -1); \x20\x20vector edges; \x20\x20for\x20(int\x20i\x20=\x200; i\x20<\x20cloud->size(); i++)\x20{ \x20\x20\x20\x20PointXYZ\x20p1\x20=\x20cloud->points[i]; \x20\x20\x20\x20for\x20(int\x20j\x20=\x20i\x20+\x201; j\x20<\x20cloud->size(); j++)\x20{ \x20\x20\x20\x20\x20\x20PointXYZ\x20p2\x20=\x20cloud->points[j]; \x20\x20\x20\x20\x20\x20float\x20dist\x20=\x20sqrt(pow(p1.x\x20-\x20p2.x, 2)\x20+\x20pow(p1.y\x20-\x20p2.y, 2)\x20+\x20pow(p1.z\x20-\x20p2.z, 2)); \x20\x20\x20\x20\x20\x20Edge\x20e\x20=\x20{\x20i, j, dist\x20}; \x20\x20\x20\x20\x20\x20edges.push_back(e); \x20\x20\x20\x20} \x20\x20}

\x20\x20sort(edges.begin(), edges.end(), cmp);

\x20\x20vector mst; \x20\x20int\x20i\x20=\x200; \x20\x20while\x20(mst.size()\x20<\x20cloud->size()\x20-\x201)\x20{ \x20\x20\x20\x20Edge\x20e\x20=\x20edges[i++]; \x20\x20\x20\x20int\x20x\x20=\x20find(parent, e.src); \x20\x20\x20\x20int\x20y\x20=\x20find(parent, e.dst); \x20\x20\x20\x20if\x20(x\x20!=\x20y)\x20{ \x20\x20\x20\x20\x20\x20mst.push_back(e); \x20\x20\x20\x20\x20\x20unionSet(parent, x, y); \x20\x20\x20\x20} \x20\x20}

\x20\x20PointCloud::Ptr\x20cloud_mst(new\x20PointCloud); \x20\x20for\x20(auto&\x20e\x20:\x20mst)\x20{ \x20\x20\x20\x20PointXYZ\x20p1\x20=\x20cloud->points[e.src]; \x20\x20\x20\x20PointXYZ\x20p2\x20=\x20cloud->points[e.dst]; \x20\x20\x20\x20cloud_mst->push_back(p1); \x20\x20\x20\x20cloud_mst->push_back(p2); \x20\x20}

\x20\x20cloud\x20=\x20cloud_mst; }

int\x20main()\x20{ \x20\x20PointCloud::Ptr\x20cloud\x20=\x20readPointCloud("D:\DIANYUNWENJIANJIA\chushigujiahua_ply.ply");

\x20\x20skeletonPruning(cloud, 3);

\x20\x20nodeClassification(cloud);

\x20\x20writePointCloud("D:\DIANYUNWENJIANJIA\gujiaxiujianhejiedianfenlei_ply.ply", cloud);

\x20\x20visualization::PCLVisualizer\x20viewer("3D\x20Viewer"); \x20\x20viewer.setBackgroundColor(0.0, 0.0, 0.0); \x20\x20viewer.addPointCloud(cloud, "cloud"); \x20\x20viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud"); \x20\x20while\x20(!viewer.wasStopped())\x20{ \x20\x20\x20\x20viewer.spinOnce(100); \x20\x20}

\x20\x20return\x200;

PCL点云骨架修剪和节点分类 - 基于阈值的骨架修剪算法

原文地址: https://www.cveoy.top/t/topic/pEZ6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录