【问题标题】:K-means clustering on point cloud data基于点云数据的 K-means 聚类
【发布时间】:2018-02-13 17:03:09
【问题描述】:

我正在尝试在点云上实现 K-means 聚类算法。但是,我不确定如何将数据导入为 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 有相当多的经验,而且这个函数在 imo 上写得不好)谢谢你的这个问题,因为我认为其他人会觉得它很有用!
  • 确实!从表面上看,这个函数似乎承担了在 PCL 中实现 kmeans 算法的所有复杂性,但在没有适当教程的情况下执行它会让人筋疲力尽。我希望它在未来对其他人有所帮助!

标签: c++ k-means point-cloud-library


【解决方案1】:

与 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”将为您提供一个向量,每个点都带有 custer 标签,您可以使用它来索引原始云并将它们分开。

【讨论】:

  • 我也看过本教程,但我尝试使用的是 PCL 中提到的 Kmeans 过滤器本身。 docs.pointclouds.org/trunk/… 在这种情况下,如您所见,我可以像过滤器一样直接启动 Kmeans,但是如果没有提到如何初始化它以及如何设置输入。此外,从点云到点向量很容易,但在 Kmeans 中只允许浮点向量作为输入。因此混乱。
  • 我现在很困惑。这是否回答你的问题...?你的代码有效吗? (*我没有对你投反对票,我只是评论说告诉你为什么人们可能会反对这个问题)
  • 我没有工作的代码。不幸的是,没有关于如何在 pcl 中直接使用 kmeans 的教程。到目前为止,我已经设法在点云中输入数据并将其传输到 PointXYZ 向量中。但是如何初始化kmeans是我很困惑的地方。
  • 谢谢!我已经添加了代码。在您的设置上尝试一下,如果我在正确的方向附近,请告诉我。
  • 实例“真实”首先没有从 PointXYZ 向量中获取输入数据,更不用说设置集群大小了。它只需要 Kmeans Point 类型向量,这对我来说是完全未知的领域。这就是我所说的缺乏教程和适当的文档的意思。
猜你喜欢
  • 2013-02-07
  • 2015-04-11
  • 2017-09-01
  • 2018-08-10
  • 2017-03-16
  • 2018-01-12
  • 2011-08-13
  • 2013-08-08
  • 2013-02-14
相关资源
最近更新 更多