【问题标题】:How to extract a set of points in a point cloud data using PCL?如何使用 PCL 在点云数据中提取一组点?
【发布时间】:2016-02-28 20:31:13
【问题描述】:

我有一个点云数据,通过单击一个点,我想提取半径内单击点周围的点。我还想将提取的点推送到新的云中。使用 Pointpickingevent,我可以单击一个点并将其推送到云中。如何提取一组点,例如从单击点开始半径 0.02 厘米的点并将它们推入新的云中?

【问题讨论】:

    标签: point-cloud-library point-clouds


    【解决方案1】:

    给定一个点云:

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud

    然后生成一个 Kdtree 来执行有效的范围搜索:

    pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
    kdtree.setInputCloud (cloud);
    

    然后,给定一个点和一个半径:

    pcl::PointXYZ searchPoint(1,2,3);
    float radius = 4;
    

    你可以得到距离searchPointradius距离的所有点:

    std::vector<int> pointIdxRadiusSearch; //to store index of surrounding points 
    std::vector<float> pointRadiusSquaredDistance; // to store distance to surrounding points
    
    if ( kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 )
    {
        for (size_t i = 0; i < pointIdxRadiusSearch.size (); ++i)
            std::cout << "    "  <<   cloud->points[ pointIdxRadiusSearch[i] ].x 
                    << " " << cloud->points[ pointIdxRadiusSearch[i] ].y 
                    << " " << cloud->points[ pointIdxRadiusSearch[i] ].z 
                    << " (squared distance: " << pointRadiusSquaredDistance[i] << ")" << std::endl;
    }
    

    您可以打印所有周围的点及其到searchPoint的距离,以检查代码功能的正确性。

    最后,用获得的点创建云:

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
    for (size_t i = 0; i < pointIdxRadiusSearch.size (); ++i)
        cloud_cluster->points.push_back(cloud->points[ pointIdxRadiusSearch[i] ]);
    cloud_cluster->width = cloud_cluster->points.size ();
    cloud_cluster->height = 1;
    cloud_cluster->is_dense = true;
    

    【讨论】:

      【解决方案2】:

      为了能够选择一个点,您可以使用类似于this answer 的 PointPickingEvent。

      .h 中的类声明,

      class PCLViewer : public QMainWindow
      {
        Q_OBJECT
      
      public:
        explicit PCLViewer (QWidget *parent = 0);
        ~PCLViewer ();
          void pointPickCallback (const pcl::visualization::PointPickingEvent& event, void*);
      
      public slots:
      
      protected:
        boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
        pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
        pcl::PointXYZ src_point_;
        bool src_point_selected_;
      
      private:
        Ui::PCLViewer *ui;
      
      };
      

      在您的 .cpp 中,

      PCLViewer::PCLViewer (QWidget *parent) :
        QMainWindow (parent),
        ui (new Ui::PCLViewer)
      {
          ui->setupUi (this);
      
          [...]
      
          viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false));
          viewer->registerPointPickingCallback (&PCLViewer::pointPickCallback, *this);
      
          [...]
      }
      

      以及附加功能,

      void
      PCLViewer::pointPickCallback (const pcl::visualization::PointPickingEvent& event, void*)
      {
        // Check to see if we got a valid point. Early exit.
        int idx = event.getPointIndex ();
        if (idx == -1)
          return;
      
        // Get the point that was picked
        event.getPoint (src_point_.x, src_point_.y, src_point_.z);
        PCL_INFO ("Src Window: Clicked point %d with X:%f Y:%f Z:%f\n", idx, src_point_.x, src_point_.y, src_point_.z);
        src_point_selected_ = true;
      }
      

      在手动注册应用中有一个更详细的使用示例: pcl/apps/src/manual_registration/manual_registration.cpp pcl/apps/include/pcl/apps/manual_registration.h

      【讨论】:

        猜你喜欢
        • 2021-07-31
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-20
        • 2018-03-29
        相关资源
        最近更新 更多