如何使用PCL移除点云中的已处理历史点以降低地图后处理耗时
全量点索引生成实现
你需要的不借助分割算法生成全量点索引的实现非常简单,直接手动填充索引即可,代码如下:
pcl::PointIndices::Ptr fInliers (new pcl::PointIndices); // 遍历当前已处理的历史点云,填充所有点的索引 for (int i = 0; i < cloud_processed->size(); ++i) { fInliers->indices.push_back(i); }
拿到全量索引后,调整ExtractIndices的参数即可过滤掉所有已处理的历史点,保留新增点:
pcl::ExtractIndices<pcl::PointXYZRGB> extract; extract.setInputCloud (total_cloud); // 传入历史点+新增点的总点云 extract.setIndices (fInliers); // 传入已处理的历史点索引 extract.setNegative(true); // 设为true表示保留索引外的点,也就是新增点 extract.filter(*new_cloud); // 输出得到仅含新增点的点云
更高性能的优化方案
上面的方法可以满足需求,但还有性能更优的实现方式,不需要调用ExtractIndices接口,可根据你的业务场景选择:
- 点云按顺序拼接的场景(推荐)
如果你的总点云是每次把新增点按顺序追加到历史点末尾,只需要记录上一次处理完成时的点云总数,直接截取对应区间的点即可,省掉索引过滤的开销:
// 全局/类成员变量,记录上一次处理完成时的点云数量 int last_processed_count = 0; // 每次迭代的处理逻辑 pcl::PointCloud<pcl::PointXYZRGB>::Ptr current_new_cloud (new pcl::PointCloud<pcl::PointXYZRGB>); // 直接截取上次处理结束位置到当前总点云末尾的所有点,即本次新增点 for (int i = last_processed_count; i < total_cloud->size(); ++i) { current_new_cloud->points.push_back(total_cloud->points[i]); } // 补齐点云必要参数 current_new_cloud->width = current_new_cloud->points.size(); current_new_cloud->height = 1; current_new_cloud->is_dense = total_cloud->is_dense; // 处理完本次新增点后,更新计数 last_processed_count = total_cloud->size();
- 点云顺序会被打乱的场景
如果你的处理流程中存在降采样、离群点去除等会修改点云顺序、删除部分历史点的操作,可以给点云增加标签字段区分已处理/未处理点,比如使用pcl::PointXYZRGBL类型,已处理的点label设为1,新增点默认label为0,遍历总点云时直接筛选label为0的点即可,稳定性更高。
内容的提问来源于stack exchange,提问作者joseandres94
相关产品推荐
相关产品推荐

