基于PCL 1.8.1库的点云PLY文件最小生成树算法可视化C++代码
#include
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud
// 边结构体,存储两个点的索引和边的权值 struct Edge { int src; int dest; float weight; };
// 并查集结构体,用于判断两个点是否在同一个集合中 struct UnionFind { int *parent, *rank; int n;
UnionFind(int n)
{
this->n = n;
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = i;
rank[i] = 0;
}
}
int find(int x)
{
if (x != parent[x])
parent[x] = find(parent[x]);
return parent[x];
}
void Union(int x, int y)
{
int xroot = find(x);
int yroot = find(y);
if (rank[xroot] < rank[yroot])
parent[xroot] = yroot;
else if (rank[xroot] > rank[yroot])
parent[yroot] = xroot;
else
{
parent[yroot] = xroot;
rank[xroot]++;
}
}
};
// 比较函数,用于对边按照权值进行排序 bool compareEdges(const Edge &e1, const Edge &e2) { return e1.weight < e2.weight; }
// Kruskal最小生成树算法
void kruskalMST(PointCloudT::Ptr cloud, std::vector
// 按照边的权值进行排序
std::sort(edges.begin(), edges.end(), compareEdges);
UnionFind uf(num_points);
for (int i = 0; i < edges.size(); i++)
{
int src_root = uf.find(edges[i].src);
int dest_root = uf.find(edges[i].dest);
// 判断两个点是否在同一个集合中,如果不在则加入最小生成树中
if (src_root != dest_root)
{
result.push_back(edges[i]);
uf.Union(src_root, dest_root);
}
}
// 可视化最小生成树
pcl::visualization::PCLVisualizer viewer('Minimum Spanning Tree');
viewer.setBackgroundColor(0.0, 0.0, 0.0);
// 将点云添加到可视化视窗中
pcl::visualization::PointCloudColorHandlerCustom<PointT> single_color(cloud, 0, 255, 0);
viewer.addPointCloud(cloud, single_color, 'cloud');
// 将最小生成树的边添加到可视化视窗中
for (int i = 0; i < result.size(); i++)
{
PointT pt1 = cloud->at(result[i].src);
PointT pt2 = cloud->at(result[i].dest);
std::stringstream ss;
ss << 'edge_' << i;
viewer.addLine(pt1, pt2, 255, 0, 0, ss.str());
}
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
}
int main() { // 加载PLY文件 PointCloudT::Ptr cloud(new PointCloudT); pcl::io::loadPLYFile('input.ply', *cloud);
// 计算点云之间的边
std::vector<Edge> edges;
for (int i = 0; i < cloud->size(); i++)
{
for (int j = i + 1; j < cloud->size(); j++)
{
Edge edge;
edge.src = i;
edge.dest = j;
edge.weight = pcl::euclideanDistance(cloud->at(i), cloud->at(j));
edges.push_back(edge);
}
}
// 使用Kruskal算法构建最小生成树并可视化
kruskalMST(cloud, edges);
return 0;
}
// 请注意,此代码仅仅对点云中的点进行了连接,并没有考虑点云的拓扑结构。如果需要构建有意义的3D模型,可以考虑使用SuperVoxel算法对点云进行分割和分析。
原文地址: https://www.cveoy.top/t/topic/o6yz 著作权归作者所有。请勿转载和采集!