Boost R树节点删除

时间:2017-08-24 08:45:01

标签: boost r-tree

我想删除最近的点节点。这应该满足距离的限制。 但我认为我的代码效率不高。 我该怎么修改呢?

    for (int j = 0; j < 3; j++) {
    bgi::rtree< value, bgi::quadratic<16> > nextRT;

    // search for nearest neighbours
    std::vector<value> matchPoints;
    vector<pair<float, float>> pointList;

    for (unsigned i = 0; i < keypoints[j + 1].size(); ++i) {
        point p = point(keypoints[j + 1][i].pt.x, keypoints[j + 1][i].pt.y);
        nextRT.insert(std::make_pair(p, i));
        RT.query(bgi::nearest(p, 1), std::back_inserter(matchPoints));

        if (bg::distance(p, matchPoints.back().first) > 3) matchPoints.pop_back();
        else {
            pointList.push_back(make_pair(keypoints[j + 1][i].pt.x, keypoints[j + 1][i].pt.y));
            RT.remove(matchPoints.back());
        }
    }

我也很好奇matchPoints的结果。 查询函数工作后,matchPoints中有值。 第一个是点,第二个看起来像一些索引号。 我不知道第二个意味着什么。

1 个答案:

答案 0 :(得分:2)

  

问。,我也很好奇matchPoints的结果。查询函数工作后,matchPoints中有值。第一个是点,第二个看起来像一些索引号。我不知道第二个意味着什么。

那么,这必须是value类型的数据成员。它的内容完全取决于您在rtree中插入的内容。如果它是描述几何的ID,我不会感到惊讶。

由于您甚至没有显示RT的类型,我们只能假设它与nextRT相同。如果是这样,我们可以假设value可能是pair<box, unsigned>对(因为你插入了什么)。因此,请查看在unsigned ...

中插入的RT值的内容
  
    

问。

  
    if (bg::distance(p, matchPoints.back().first) > 3) matchPoints.pop_back();
    else {
        pointList.push_back(make_pair(keypoints[j + 1][i].pt.x, keypoints[j + 1][i].pt.y));
        rtree.remove(matchPoints.back());
    }

简化您的代码!提炼要求:

  1. 在我看来,对于4组“关键点”,你想创建包含所有这些关键点的4 rtrees,并且顺序增加id。

  2. 对于这4组“关键点”,您还要创建一个关键点列表,可以找到半径为3的几何体。

    作为副作用,请从原始rtree RT中删除那些紧密匹配的几何图形。

  3.   

    决策:因为这些任务是独立的,所以让我们分开:

    // making up types that match the usage in your code:
    struct keypoint_t { point pt; };
    std::array<std::vector<keypoint_t>, 4> keypoints;
    

    现在,让我们完成任务:

    1. 注意这里不使用RT:

      for (auto const& current_key_set : keypoints) {
          bgi::rtree< value, bgi::quadratic<16> > nextRT; // use a better name...
      
          int i = 0;
          for (auto const& kpd : current_key_set)
              nextRT.insert(std::make_pair(kpd.pt, i++));
      }
      
    2. 创建包含匹配关键点的向量(RT中具有近似几何的那些):

      for (auto const& current_key_set : keypoints) {
          std::vector<point> matched_key_points;
      
          for (auto const& kpd : current_key_set) {
              point p = kpd.pt;
      
              value match;
              if (!RT.query(bgi::nearest(p, 1), &match))
                  continue;
      
              if (bg::distance(p, match.first) <= 3) {
                  matched_key_points.push_back(p);
                  RT.remove(match);
              }
          }
      }
      
    3. 具有讽刺意味的是,从RT中删除匹配的几何会成为一个小问题:您可以通过迭代器或值删除。在这种情况下,我们使用带有value的重载。

      摘要

      很难理解代码,看看它做了什么。我已经展示了如何清理代码并使其工作。也许这些不是你 需要 的东西,但希望使用更好的分离代码,你应该能够更进一步。

      请注意,算法有副作用。这使得很难理解真正发生的事情。 E.g:

      • 从原始RT中删除点会影响后续关键点(即使是后续集合(下一个j))可以与
      • 匹配
      • 如果你有多次相同的关键点,它们可能匹配超过1个源RT点(因为删除第一个匹配后,半径3内可能会有第二个匹配)
      • 严格按顺序检查关键点。这意味着如果第一个关键点与点X大致匹配,这可能会导致稍后的关键点失败匹配,即使X点可能更接近该关键点...

      我建议你在实施具有这些副作用的事情之前真正思考这些要求。 ** Study the sample cases in the live demo below。如果所有这些副作用都是您想要的,请确保使用更好的命名和正确的注释来描述代码正在做什么。

      现场演示

      <强> Live On Coliru

      #include <boost/geometry.hpp>
      #include <boost/geometry/io/io.hpp>
      #include <boost/geometry/index/rtree.hpp>
      #include <iostream>
      
      namespace bg  = boost::geometry;
      namespace bgi = bg::index;
      
      typedef bg::model::point<float, 2, bg::cs::cartesian> point;
      
      typedef std::pair<point, unsigned> pvalue;
      typedef pvalue value;
      
      int main() {
          bgi::rtree< value, bgi::quadratic<16> > RT;
      
          {
              int i = 0;
              for (auto p : { point(2.0f, 2.0f), point(2.5f, 2.5f) })
                  RT.insert(std::make_pair(p, i++));
          }
      
          struct keypoint_t { point pt; };
          using keypoints_t = std::vector<keypoint_t>;
      
          keypoints_t const keypoints[] = {
              keypoints_t{ keypoint_t { point(-2, 2)  } },  // should not match anything
              keypoints_t{ keypoint_t { point(-1, 2)  } },  // should match (2,2)
              keypoints_t{ keypoint_t { point(2.0, 2.0) },  // matches (2.5,2.5)
                                      { point(2.5, 2.5) },  // nothing anymore...
                         },
          };
      
          for (auto const& current_key_set : keypoints) {
              bgi::rtree< pvalue, bgi::quadratic<16> > nextRT; // use a better name...
      
              int i = 0;
              for (auto const& kpd : current_key_set)
                  nextRT.insert(std::make_pair(kpd.pt, i++));
          }
      
          for (auto const& current_key_set : keypoints) {
              std::cout << "-----------\n";
              std::vector<point> matched_key_points;
      
              for (auto const& kpd : current_key_set) {
                  point p = kpd.pt;
                  std::cout << "Key: " << bg::wkt(p) << "\n";
      
                  value match;
                  if (!RT.query(bgi::nearest(p, 1), &match))
                      continue;
      
                  if (bg::distance(p, match.first) <= 3) {
                      matched_key_points.push_back(p);
                      std::cout << "\tRemoving close point: " << bg::wkt(match.first) << "\n";
                      RT.remove(match);
                  }
              }
      
              std::cout << "\nMatched keys: ";
              for (auto& p : matched_key_points)
                  std::cout << bg::wkt(p) << " ";
              std::cout << "\n\tElements remaining: " << RT.size() << "\n";
          }
      
      }
      

      打印

      -----------
      Key: POINT(-2 2)
      
      Matched keys: 
          Elements remaining: 2
      -----------
      Key: POINT(-1 2)
          Removing close point: POINT(2 2)
      
      Matched keys: POINT(-1 2) 
          Elements remaining: 1
      -----------
      Key: POINT(2 2)
          Removing close point: POINT(2.5 2.5)
      Key: POINT(2.5 2.5)
      
      Matched keys: POINT(2 2) 
          Elements remaining: 0