比较两个点云相似度的指标

Arm*_*ino 3 point-clouds point-cloud-library

有哪些指标或方法被广泛用于比较两个点云对象的相似性?(例如,它可以是 PCD 文件或 PLY 文件)。

我在PCL库的文档中搜索过但没有找到。谷歌搜索,发现了一些研究,但他们谈论的是新方法,而不是广泛或已经使用的方法。

有没有比较点云相似度的基本方法?或者甚至是 PCL 库中的某些函数可以完成这项工作?

kan*_*tar 7

这是我的方法:

    #include <algorithm>
    #include <numeric>
    
    #include <pcl/point_cloud.h>
    #include <pcl/point_types.h>
    #include <pcl/common/geometry.h>
    #include <pcl/search/kdtree.h>
    
    template<typename TreeT, typename PointT>
    float nearestDistance(const TreeT& tree, const PointT& pt)
    {
      const int k = 1;
      std::vector<int> indices (k);
      std::vector<float> sqr_distances (k);
    
      tree.nearestKSearch(pt, k, indices, sqr_distances);
    
      return sqr_distances[0];
    }
    
    // compare cloudB to cloudA
    // use threshold for identifying outliers and not considering those for the similarity
    // a good value for threshold is 5 * <cloud_resolution>, e.g. 10cm for a cloud with 2cm resolution
    template<typename CloudT>
    float _similarity(const CloudT& cloudA, const CloudT& cloudB, float threshold)
    {
      // compare B to A
      int num_outlier = 0;
      pcl::search::KdTree<typename CloudT::PointType> tree;
      tree.setInputCloud(cloudA.makeShared());
      auto sum = std::accumulate(cloudB.begin(), cloudB.end(), 0.0f, [&](auto current_sum, const auto& pt) {
        const auto dist = nearestDistance(tree, pt);
    
        if(dist < threshold)
        {
          return current_sum + dist;
        }
        else
        {
          num_outlier++;
          return current_sum;
        }
      });
    
      return sum / (cloudB.size() - num_outlier);
    }
    
    // comparing the clouds each way, A->B, B->A and taking the average
    template<typename CloudT>
    float similarity(const CloudT& cloudA, const CloudT& cloudB, float threshold = std::numeric_limits<float>::max())
    {
      // compare B to A
      const auto similarityB2A = _similarity(cloudA, cloudB, threshold);
      // compare A to B
      const auto similarityA2B = _similarity(cloudB, cloudA, threshold);
    
      return (similarityA2B * 0.5f) + (similarityB2A * 0.5f);
    }
Run Code Online (Sandbox Code Playgroud)

这个想法是,通过搜索 B 的每个点到邻居的最近距离来比较点云 B 和 A。通过对找到的距离进行平均(排除异常值),您可以很好地估计相似性。