基于pcl库以已知点p为起点的kmean聚类的c++代码
以下是一个基于PCL库的C++代码示例,用于实现基于已知点p为起点的K-means聚类:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/visualization/cloud_viewer.h>
int main(int argc, char** argv)
{
// 加载点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read<pcl::PointXYZ>("input_cloud.pcd", *cloud);
// 创建法线估计对象
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud(cloud);
// 创建一个空的kdtree对象,并把它传递给法线估计对象
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
ne.setSearchMethod(tree);
// 容器存储输出的法线
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
// 估计法线
ne.setKSearch(10); // 设置k近邻搜索的数量
ne.compute(*cloud_normals);
// 创建一个空的kd树对象,并把它传递给聚类对象
pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>());
// 创建一个向量存储点云索引
std::vector<pcl::PointIndices> cluster_indices;
// 创建欧氏聚类对象
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance(0.02); // 设置聚类的容差
ec.setMinClusterSize(100); // 设置聚类的最小点数
ec.setMaxClusterSize(25000); // 设置聚类的最大点数
ec.setSearchMethod(kdtree);
ec.setInputCloud(cloud);
ec.setIndices(cloud_normals);
// 执行聚类
ec.extract(cluster_indices);
// 创建可视化对象
pcl::visualization::PCLVisualizer viewer("Cluster viewer");
// 设置背景颜色
viewer.setBackgroundColor(0, 0, 0);
// 设置点云颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0);
viewer.addPointCloud<pcl::PointXYZ>(cloud, single_color, "input_cloud");
// 遍历所有聚类
int cluster_id = 0;
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it)
{
// 创建一个新的点云数据对象,用于存储当前聚类的点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cluster_cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 遍历当前聚类的所有点
for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
{
// 将当前点添加到聚类点云数据对象中
cluster_cloud->points.push_back(cloud->points[*pit]);
}
// 设置聚类点云数据对象的属性
cluster_cloud->width = cluster_cloud->points.size();
cluster_cloud->height = 1;
cluster_cloud->is_dense = true;
// 设置聚类点云数据对象的颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cluster_color(cluster_cloud, rand() % 255, rand() % 255, rand() % 255);
std::string cluster_name = "cluster_" + std::to_string(cluster_id);
viewer.addPointCloud<pcl::PointXYZ>(cluster_cloud, cluster_color, cluster_name);
// 显示当前聚类的点云数据对象
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, cluster_name);
// 增加聚类ID
cluster_id++;
}
// 显示点云数据
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
请注意,此代码假设您已经安装了PCL库,并且将输入点云数据保存在名为"input_cloud.pcd"的文件中。您还可以根据需要调整聚类的参数,例如聚类的容差、最小点数和最大点数。
原文地址: https://www.cveoy.top/t/topic/hWT7 著作权归作者所有。请勿转载和采集!