#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;