点云数据的 K 均值聚类
K-means clustering on point cloud data
我正在尝试在点云上实施 K 均值聚类算法。但是,我不确定如何将数据导入为 pcl 的 k-means 成员的输入。文档已被证明有点混乱。
到目前为止,我已经将 pcd 导入点云并将其转换为矢量,但我不知道如何从这里开始并直接初始化 Kmeans。
int main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
std::vector<pcl::PointXYZ> cloud;
pcl::io::loadPCDFile ("Scene02 - Cloud.pcd", *cloud_in);
for (int i = 0; i < cloud_in->size(); i++)
{
cloud[i] = cloud_in->points[i];
}
pcl::Kmeans real(300000, 3);
real.setInputData(cloud);
}
我意识到语法错误,但我也不确定正确的语法是什么。
与 pcl 通常的操作方式(以自定义点类型为中心)相比,此功能非常奇怪。基本上,奇怪的是您必须通过指定的维度向量而不是自定义点类型来输入点。这是经过测试的功能示例代码:(显然您需要提供自己的文件名,并且您可能需要调整簇大小)
int main(int argc, char** argv) {
std::string filePath = "../PointCloudFiles/beaconJR.pcd";
pcl::PointCloud<pcl::PointXYZ>::Ptr tempCloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile(filePath, *tempCloud) == -1) //* load the file
{printf("failed file load!\n");}
else
{
pcl::Kmeans real(static_cast<int> (tempCloud->points.size()), 3);
real.setClusterSize(3); //it is important that you set this term appropriately for your application
for (size_t i = 0; i < tempCloud->points.size(); i++)
{
std::vector<float> data(3);
data[0] = tempCloud->points[i].x;
data[1] = tempCloud->points[i].y;
data[2] = tempCloud->points[i].z;
real.addDataPoint(data);
}
real.kMeans();
// get the cluster centroids
pcl::Kmeans::Centroids centroids = real.get_centroids();
std::cout << "points in total Cloud : " << tempCloud->points.size() << std::endl;
std::cout << "centroid count: " << centroids.size() << std::endl;
for (int i = 0; i<centroids.size(); i++)
{
std::cout << i << "_cent output: x: " << centroids[i][0] << " ,";
std::cout << "y: " << centroids[i][1] << " ,";
std::cout << "z: " << centroids[i][2] << std::endl;
}
}
std::cin.get();
std::cin.get();
}
干杯!
--编辑
就可视化集群而言。我认为(未经测试)"pcl::Kmeans::PointsToClusters" 将为您提供一个向量,每个点都带有聚类标签,您可以使用它来索引原始云并将它们分开。
我正在尝试在点云上实施 K 均值聚类算法。但是,我不确定如何将数据导入为 pcl 的 k-means 成员的输入。文档已被证明有点混乱。 到目前为止,我已经将 pcd 导入点云并将其转换为矢量,但我不知道如何从这里开始并直接初始化 Kmeans。
int main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
std::vector<pcl::PointXYZ> cloud;
pcl::io::loadPCDFile ("Scene02 - Cloud.pcd", *cloud_in);
for (int i = 0; i < cloud_in->size(); i++)
{
cloud[i] = cloud_in->points[i];
}
pcl::Kmeans real(300000, 3);
real.setInputData(cloud);
}
我意识到语法错误,但我也不确定正确的语法是什么。
与 pcl 通常的操作方式(以自定义点类型为中心)相比,此功能非常奇怪。基本上,奇怪的是您必须通过指定的维度向量而不是自定义点类型来输入点。这是经过测试的功能示例代码:(显然您需要提供自己的文件名,并且您可能需要调整簇大小)
int main(int argc, char** argv) {
std::string filePath = "../PointCloudFiles/beaconJR.pcd";
pcl::PointCloud<pcl::PointXYZ>::Ptr tempCloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile(filePath, *tempCloud) == -1) //* load the file
{printf("failed file load!\n");}
else
{
pcl::Kmeans real(static_cast<int> (tempCloud->points.size()), 3);
real.setClusterSize(3); //it is important that you set this term appropriately for your application
for (size_t i = 0; i < tempCloud->points.size(); i++)
{
std::vector<float> data(3);
data[0] = tempCloud->points[i].x;
data[1] = tempCloud->points[i].y;
data[2] = tempCloud->points[i].z;
real.addDataPoint(data);
}
real.kMeans();
// get the cluster centroids
pcl::Kmeans::Centroids centroids = real.get_centroids();
std::cout << "points in total Cloud : " << tempCloud->points.size() << std::endl;
std::cout << "centroid count: " << centroids.size() << std::endl;
for (int i = 0; i<centroids.size(); i++)
{
std::cout << i << "_cent output: x: " << centroids[i][0] << " ,";
std::cout << "y: " << centroids[i][1] << " ,";
std::cout << "z: " << centroids[i][2] << std::endl;
}
}
std::cin.get();
std::cin.get();
}
干杯!
--编辑
就可视化集群而言。我认为(未经测试)"pcl::Kmeans::PointsToClusters" 将为您提供一个向量,每个点都带有聚类标签,您可以使用它来索引原始云并将它们分开。