【问题标题】:Point Cloud Library (PCL) : Extract only the vertices of a surface点云库 (PCL) :仅提取曲面的顶点
【发布时间】:2021-07-31 21:10:04
【问题描述】:

我在使用 PCL 库时需要一些帮助。我只是点云的初学者。

我有一个大的点云,我可以从中提取平面。我最终得到了 6 个表面,每个表面分别存储在不同的点云中。我使用 XYZRGB 点。然而,每个点云最终都会有数千个点。The surfaces ploted using matplotlib

pcl::PointCloud<pcl::PointXYZRGB>::Ptr Surfacei

Size of Surface1 before : 216224 
Size of Surface2 before : 5407 
Size of Surface3 before : 4168 
Size of Surface4 before : 7298 
Size of Surface5 before : 5621 
Size of Surface6 before : 30474 

但是,我需要减少这个点数,因为它对我的需要来说确实很大。我最终通过这样做使用了 pcl::ConvexHull 类:

pcl::ConvexHull<pcl::PointXYZRGB> chull;
chull.setInputCloud(Surfacei);
chull.reconstruct(*Surfacei);

点数明显减少:

Size of Surface1 before : 30 
Size of Surface2 before : 21 
Size of Surface3 before : 127 
Size of Surface4 before : 21 
Size of Surface5 before : 25 
Size of Surface6 before : 17 

The news plot looks like this

由于平面是四边形,我只想提取每个平面的顶点坐标,但找不到任何帮助。

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: c++ ros point-cloud-library point-clouds


    【解决方案1】:

    我认为使用凸包将帮助您找到覆盖所有点以及相应多边形边缘和顶点的最小多边形。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。
    【解决方案2】:

    在下面的一段代码中,我从一个点云(cloud)中提取主平面(最大的大致平面)到一个新的点云(cloud_segmented)。我可以保证这是可行的。从这个平面上,您可以通过找到极坐标轻松提取顶点。但是,您需要弄清楚如何扩展它以获得多个平面。

    另外,在您的特定示例中,您是否将提取的表面可视化?如果您确实获得了点曲面,则可以轻松提取极值点以获取顶点。

        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::PointCloud<pcl::PointXYZ> cloud_segmented;
    
        pcl::ModelCoefficients coefficients;
        pcl::PointIndices::Ptr inliers(new pcl::PointIndices());
    
        pcl::SACSegmentation<pcl::PointXYZ> segmentation;
        segmentation.setModelType(pcl::SACMODEL_PLANE);
        segmentation.setMethodType(pcl::SAC_RANSAC);
        segmentation.setMaxIterations(1000);
        segmentation.setDistanceThreshold(0.01);
        segmentation.setInputCloud(cloud.makeShared());
        segmentation.segment(*inliers, coefficients);
    
        pcl_msgs::ModelCoefficients ros_coefficients;
        pcl_conversions::fromPCL(coefficients, ros_coefficients);
        ros_coefficients.header.stamp = input.header.stamp;
        coef_pub.publish(ros_coefficients);
    
        pcl_msgs::PointIndices ros_inliers;
        pcl_conversions::fromPCL(*inliers, ros_inliers);
        ros_inliers.header.stamp = input.header.stamp;
        ind_pub.publish(ros_inliers);
    
        pcl::ExtractIndices<pcl::PointXYZ> extract;
        extract.setInputCloud(cloud.makeShared());
        extract.setIndices(inliers);
        extract.setNegative(false);
        extract.filter(cloud_segmented);
    

    【讨论】:

    • 感谢您的回答。事实上,我已经在不同的点云中拥有了每个表面,但是每个表面的点数对于我需要的来说太大了。 convexhull.reconstruct 方法有助于减少它,但数量仍然太大并且点没有排序。当我绘制它们时,这就是我得到的:i.stack.imgur.com/JyaUX.png 我不能简单地提取极值点,因为它必须是一种通用方法,并且曲面不能只是四边形
    【解决方案3】:

    如果您想减少点云中的点数,可以使用 VoxelGrid 过滤器。

    Official Tutorial: Downsampling a PointCloud using a VoxelGrid filter

    使用示例(来自上面的教程):

      pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
      sor.setInputCloud (cloud);
      sor.setLeafSize (0.01f, 0.01f, 0.01f);
      sor.filter (*cloud_filtered);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      相关资源
      最近更新 更多