首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于PCL和RANSAC的墙体检测

基于PCL和RANSAC的墙体检测
EN

Stack Overflow用户
提问于 2020-08-03 21:31:59
回答 1查看 1.6K关注 0票数 0

我一直在使用PCL (点云库)在PCD (Point )文件中进行墙壁检测。PCD文件是通过深度摄像机生成的。我发现在许多类似的应用中,例如地板检测,RANSAC已经被使用。因此,我也想在这里应用RANSAC,我尽力理解RANSAC,但我仍然有一些与我的应用程序相关的问题:

  1. 简而言之,RANSAC试图删除给定数据中的异常值,并迭代地通过一个模型推广这些异常值。那么,在地板检测的情况下,它会把与其他物体对应的点云的其余部分看作是孤立点,而将地板看作是异常点吗?墙壁也是这样吗?
  2. 根据PCL的平面模型分割教程,RANSAC是通过coefficients->values向量给出平面方程中的模型平面的系数,即abcd。所以,我假设,在壁面探测的情况下,它会试图给出与墙对应的平面方程。然而,如果深度摄像机在房间的一角,而墙壁的顶部视图是这样的,那该怎么办:

商业、金融等行业。

______________

|

|

.=‘2’>.=‘2’>.

|

|

因此,在这种情况下,所得到的模型平面是什么样子的?这会不会是一种再转轨,再转轨(制造一个三角形)?

商业、金融等行业。

.

|

商业、商业、金融、金融、商业、金融、商业、金融等行业的自愿性、商品性等。

|

即使在这种情况下,它会是什么样子呢?

  1. 根据PCL的从PointCloud教程中提取索引算法,基于分割算法输出的索引,利用ExtractIndices <pcl::ExtractIndices>滤波器从点云中提取点的子集。但是,这个过滤器到底在做什么呢?事实上,在地面探测或墙壁探测(假设只有一个直墙)情况下,RANSAC已经给出了一个平面方程。那么,有必要使用这个过滤器吗?如果是的话,那为什么,怎么做?
  2. 在以下情况下,如何检测多个墙壁?ExtractIndices <pcl::ExtractIndices>过滤器可以做到这一点?如果是,那怎么做?

商业、金融等行业。

.

|

商业、商业、金融、金融、商业、金融、商业、金融等行业的自愿性、商品性等。

|

如果你认为有比使用RANSAC更好的方法,那么也请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2021-07-24 14:13:08

你问的几个问题的答案:

据我所知,在使用平面模型的情况下,RANSAC随机从云中选取3个点,并将其视为一个平面。(这是一个稍后将得到证实的临时声明)所有靠近该平面的点,作为垂直距离的给定阈值被认为是不稳定点。算法还给出了其中包含最多点的平面(发现的平面也取决于你选择的迭代次数,如果它太低,它可能错过了最大的平面)。在墙壁的情况下,故事是一样的。你可以搜索飞机,但应该选择好搜索方向。墙壁随意垂直于平面x-y。参数的设置应该考虑到这一点。示例:

代码语言:javascript
复制
pcl::SACSegmentation<pcl::PointXYZI> seg;
Eigen::Vector3f axis;

//HELPER VARIABLES
float angle = 12.0;
void set_segmentation(float threshold, int max_iteration, float probability) {
    seg.setModelType(pcl::SACMODEL_PERPENDICULAR_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    // set cloud, threshold, and other paramatres
    seg.setDistanceThreshold(threshold);//Distance need to be adjusted according 
    to the obj
    seg.setMaxIterations(max_iteration);
    seg.setProbability(probability);
}  
PlaneSegment(float x, float y, float z, float set_angle, float threshold, int 
max_iteration, float probability) {
    axis = Eigen::Vector3f(x, y, z);
    angle = set_angle;
    seg.setAxis(axis);
    seg.setEpsAngle(angle * (3.1415 / 180.0f));
    //SET SEGMENTATION
    set_segmentation(threshold, max_iteration, probability);
}
pcl::PointIndices::Ptr segment_plane(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud, 
pcl::PointIndices::Ptr inliers) {
    seg.setInputCloud(cloud);
    seg.segment(*inliers, *coefficients);
    if (inliers->indices.size() == 0)
    {
        PCL_ERROR("COULD NOT ESTIMATE PLANAR MODEL.\n");
        exit(-1);
    }
    return inliers;
}

pcl::PointCloud<pcl::PointXYZI>::Ptr 
extraction(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud, pcl::PointIndices::Ptr 
inliers) {
    extract.setInputCloud(cloud);
    extract.setIndices(inliers);
    extract.setNegative(true);
    extract.filter(*cloud);
    return cloud;
}

您可以设置一个接受角,在这种情况下,12度,以及搜索方向的基础上的轴线。

关于你的第二点:

在多面墙的情况下,它会还给出包含最多点的墙。但如果需要的话,你也应该可以提取其他的飞机。(建议,保存所有包含比你选择的阈值更多的点的飞机)我在你的问题之后,这也是一个解决方案:pcl::RANSAC分割,所有的平面都在云中?。首先,评论给出了很好的回答。

第三点:

检查示例代码。注意,这是一个类,所以有一个构造函数。segment_plane函数返回inliers。在此基础上,您可以调用提取函数,并从云中删除不正确的元素。这是一个非常简单和快速的解决办法。您可以避免使用系数值所带来的痛苦。另外,如果你不想移除它们,只需用迭代的方法将它们涂上颜色,并将其强度设置为选定的值。

RANSAC算法可以是健壮的,但有时它确实不起作用。而且,由于迭代次数的关系,它可能会很慢。解决这个问题的方法有很多种。举个例子:考虑云下面的网格。很多大小相等的方形细胞。在每个单元格中,检查最小和最大点高度。在此基础上,您可以得到地面平面(如果这些值只是稍微不同,并且彼此接近)。最大高度和最小高度的差异在地面细胞或墙壁上是很小的。有了墙,你可以假设点在每个单元格中的分布是均匀的,最大-最小值的差异很大。诚挚的问候。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63237222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档