通过帧间确定动态障碍物,剔除动态3D点云数据后用于生成栅格地图

在使用rtabmap建图时,障碍物层的栅格地图无法清除动态障碍物,对于3D障碍物点云仅仅是简单的累加的过程!
因此尝试通过两帧之间的变化消除动态障碍物点云。

MapsManager.cpp中剔除动态障碍物

ROS_INFO("x:%fs,y:%fs,z:%fs",iter->second.x(),iter->second.y(),iter->second.z());

在这里插入图片描述
首先在该cpp文件中确定了里程计pose,利用该pose进行cropBoxFilter过滤
在这里插入图片描述
在更新障碍物的过程中,将之前简单的累加,先改成如下所示,确定一下剔除的范围:

//like
pcl::CropBox<pcl::PointXYZRGB> cropBoxFilter;
double x_min = +iter->second.x()-1;
   double y_min = +iter->second.y()-1;
   double z_min = +iter->second.z()-1;
   double x_max = +iter->second.x()+1;
   double y_max = +iter->second.y()+1;
   double z_max = +iter->second.z()+1;
   cropBoxFilter.setMin(Eigen::Vector4f(x_min, y_min, z_min, 1.0));
   cropBoxFilter.setMax(Eigen::Vector4f(x_max, y_max, z_max, 1.0));
   cropBoxFilter.setNegative(false); 
   cropBoxFilter.setInputCloud(subtractedCloud);
   cropBoxFilter.filter(*subtractedCloud);
*assembledObstacles_=*subtractedCloud;

可以看见,此时只保留了每一帧中的附近二米内的障碍物点云
在这里插入图片描述
接下来定义俩点云数据,注意智能指针初始化!

lastObstacles(new pcl::PointCloud<pcl::PointXYZRGB>),
currentObstacles(new pcl::PointCloud<pcl::PointXYZRGB>),

首先简单的确定一下静态障碍物,即在上一帧和当前帧重叠的区域里,上一帧存在的点云在该帧同样存在,简单理解就是该障碍物在这两帧中处于同样的位置,即静止状态!如果要区分动态和静态障碍物,还需要设计更加严格的判断规则。

这里,我使用的kdtree查找最近点,来判断上一帧的点云在该帧同样位置是否存在!由于对PCL库的使用不熟悉,如果有更好的方法,欢迎私信留言!

if(lastObstacles->size()){                            
    //创建kdtree 结构                            
    ROS_INFO("create kdtree");                            
    for(unsigned int i=0; i<lastObstacles->size(); ++i){                                
        pcl::PointXYZRGB searchPoint;                                
        searchPoint.x = lastObstacles->at(i).x;                                
        searchPoint.y = lastObstacles->at(i).y;                                
        searchPoint.z = lastObstacles->at(i).z;
        if(fabs(searchPoint.x - iter->second.x()) <3 &&fabs(searchPoint.y - iter->second.y()) <3 &&fabs(searchPoint.z - iter->second.z()) <3){                                    
          	 //确定是否为静态障碍物
         	  ...
           }                            
     }                           
     //剔除掉不为静态障碍物的点云     
     *currentObstacles+=*lastObstacles;                   
}                        
*lastObstacles = *subtractedCloud;

首先判断上一帧的点云数据,是否在该帧内,即:

fabs(searchPoint.x - iter->second.x()) <3 &&fabs(searchPoint.y - iter->second.y()) <3 &&fabs(searchPoint.z - iter->second.z()) <3

如果在该帧内的话,则在该帧的区域内去查找,上一帧中出现的点云是否依然存在,这里考虑到里程计的误差,将radius设置为0.08,如果发现该点,则认为该点为静态障碍物,则保留,否则将过滤剔除掉!

pcl::KdTreeFLANN<pcl::PointXYZRGB> kdtree;                                    
kdtree.setInputCloud(subtractedCloud);                                    
std::vector<int> pointIdxRadiusSearch;                                    
std::vector<float> pointRadiusSquaredDistance;                                    
float radius = 0.08;                                    
if ( kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 ){                                            
    inliers->indices.push_back(i);                                    
}                                

当确定好静态障碍物之后,通过ExtractIndices分割算法提取静态部分点云数据。

extract.setInputCloud(lastObstacles);                            
extract.setIndices(inliers);                           
extract.setNegative(false);                            
extract.filter(*lastObstacles);                            
ROS_INFO("lastObstacles point size:%d",(int)lastObstacles->size());                           

在该方法中,每次都是在下一帧中确定上一帧里的障碍物点是否可以加到障碍物层中,而本帧的障碍物点云,则是直接拼接上去:

*assembledObstacles_ = *currentObstacles + *subtractedCloud;

这样则每次保留了最新帧的所有障碍物点云,和之前帧里认为是静态障碍物的点云,此时可以明显的剔除掉大部分的动态障碍物点云。

未剔除动态障碍物点云如下所示,可以明显的看到身边走动的人留下的点:
在这里插入图片描述
在经过动态剔除之后,可以看见基本上能去除所有动态的点云:
在这里插入图片描述
去除掉动态障碍物之后,便可以使用该点云数据,来生成2D栅格地图,用于路径规划!!
目前只是简单的尝试了一下,细节部分还有待优化。


补充:在Lio_livox中也对动态障碍物进行了处理,其中把点云分为前景,背景,面特征,角特征。其中前景点被认为是动态物体,在特征提取过程中被排除。

There are also some parameters in the config file:
Use_seg: choose the segmentation mode for dynamic objects filtering, there are 2 modes:
0 - without using the segmentation method, you can choose this mode if there is few dynamic objects in your data
1 - using the segmentation method to remove dynamic objects

SegBG函数中,对于地面以上的点云进行处理,从上往下增长,这里种子阈值被设置为4~6m,认为达到这种高度为背景,其他为前景。

SegBG(pLabel,cloud,kdtree,0.5); //背景label=1 前景0

在选择一遍前景后,剩下的都是最高高度在4m以下的点云类。再通过FindACluster进一步确定是否为前景。只有当pLabel仍然等于0的才会被认为时前景,即动态障碍物。

 // cluster 分类
float dx=cf.xmax-cf.xmin;
float dy=cf.ymax-cf.ymin;
float dz=cf.zmax-cf.zmin;
float cx=10000;
for(int ii=0;ii<pnum;ii++){
    if (cx>cloud->points[pid].x)    {
        cx=cloud->points[pid].x;
    }
}
if((dx>15)||(dy>15)||((dx>10)&&(dy>10)))// 太大{
    isBg=2;
}
else if(((dx>6)||(dy>6))&&(cf.zmean < 1.5))//长而过低{
    isBg = 3;//1;//2;
}
else if(((dx<1.5)&&(dy<1.5))&&(cf.zmax>2.5))//小而过高{
    isBg = 4;
}
else if(cf.pnum<5 || (cf.pnum<10 && cx<50)) //点太少{
    isBg=5;
}
else if((cf.zmean>3)||(cf.zmean<0.3))//太高或太低{
    isBg = 6;//1;
}
if(isBg>0){
    for(int ii=0;ii<pnum;ii++)    {
        if(pLabel[ii]==labelId)        {
            pLabel[ii]=isBg;
        }
    }
}
else{
    labelId++;
}

具体代码如上,源码地址:https://github.com/Livox-SDK/LIO-Livox

  • 17
    点赞
  • 144
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
### 回答1: 可以使用点云配准算法将多个激光雷达扫描的点云数据进行配准,然后将配准后的点云数据转换为栅格地图。具体的方法包括:将点云数据进行滤波、分割、聚类等预处理操作,然后使用栅格化算法将点云数据转换为栅格地图。最后,可以使用地图匹配算法将机器人在栅格地图上的位置进行估计和更新。 ### 回答2: 利用激光雷达点云数据建立栅格地图是通过将三维点云数据转化为二维栅格地图来实现的。下面是具体的步骤: 1. 数据预处理:在建立栅格地图之前,需要对激光雷达点云进行一些预处理,如去除离群点、滤除地面点等。去除离群点可以通过统计每个点的邻域点的平均距离,通过比较与阈值的差异来确定是否为离群点。滤除地面点可以通过平面拟合算法来实现。 2. 栅格划分:将整个区域划分为一定大小的栅格,可以根据需要调整栅格的大小,通常是正方形或矩形。 3. 点云投影:将激光雷达点云中的每个点投影到所在的栅格中。可以通过计算点到栅格边界的最小距离来确定点所在的栅格。 4. 栅格更新:根据点云数据的信息更新每个栅格中的值。可以根据需要选择更新的方式,如只更新栅格是否被占用、栅格是响应强度还是距离等。 5. 地图生成:根据栅格中的信息生成栅格地图,可以使用不同的颜色或灰度表示不同的属性,如占用栅格和自由栅格等。 值得注意的是,在建立栅格地图的过程中,需要考虑激光雷达的分辨率、栅格的大小和更新频率等因素。此外,对于大规模的场景,如果点云密度较高,可以考虑使用分块处理的方法,将整个区域划分为多个子区域来处理,以减少计算量。 总的来说,利用激光雷达点云数据建立栅格地图是一种常用的方法,可以为机器人导航、环境建模等应用提供基础数据。 ### 回答3: 激光雷达点云数据可以通过一系列步骤来建立栅格地图。首先,需要对点云数据进行预处理。这包括去除离群点、滤除地面点和提取感兴趣的对象等。其次,需要对点云数据进行地面分割,将地面点和非地面点分开。这可以通过利用地面的平面特征进行分割,例如RANSAC算法。接下来,需要对非地面点进行聚类,将相邻的点归为同一类。这可以通过基于密度的聚类算法(如DBSCAN)来实现。然后,可以根据点云数据生成栅格地图。对于每个栅格,在点云中找到位于该栅格内的点,并将它们的位置信息用来表示栅格地图中的障碍物。最后,可以将栅格地图进行反馈优化,填充栅格地图中的空洞,并去除栅格地图中的噪声。这可以通过使用滤波和插值等技术来实现。通过以上步骤,激光雷达点云数据可以成功建立栅格地图,以实现对环境的感知和导航。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃头队长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值