三维pcd地图转二维栅格地图

1.概述

在使用导航时,通常会根据二维栅格地图做路径规划,需要将三维点云地图转化成栅格地图。
本文采用滤波及投影的方法,
主要步骤包括

  • 对输入点云进行直通滤波,获取限定高度范围的数据
  • 在进行半径滤波,去除部分孤立点
  • 转换为栅格地图

2.方法说明

完整程序代码:github

运行方法:
下载编译后,

mkdir -p test_ws/src&& cd test_ws/src
git clone -b develop  https://github.com/Hinson-A/pcd2pgm_package
cd ../
catkin_make

编译完成后,查看 src/pcd2pgm_package/pcd2pgm/launch/中的run.launch文件,修改相应的文件路径及名称

launch文件如下

<!-- -->
<launch>
<node pkg="pcd2pgm" name="pcd2pgm" type="pcd2pgm" output="screen">
<!-- 存放pcd文件的路径-->
<param name="file_directory" value= "/home/robot/map/" />
<!-- pcd文件名称-->
<param name="file_name" value= "map" />
<!-- 选取的范围 最小的高度-->
<param name="thre_z_min" value= "0.1" />
<!-- 选取的范围 最大的高度-->
<param name="thre_z_max" value= "1.5" />
<!--0 选取高度范围内的,1选取高度范围外的-->
<param name="flag_pass_through" value= "0" />
<!-- 半径滤波的半径-->
<param name="thre_radius" value= "0.5" />
<!-- 半径滤波的要求点数个数-->
<param name="thres_point_count" value= "10" />
<!-- 存储的栅格map的分辨率-->
<param name="map_resolution" value= "0.05" />
<!-- 转换后发布的二维地图的topic,默认使用map即可,可使用map_server保存-->
<param name="map_topic_name" value= "map" />
</node>

</launch>

修改完成后,运行程序

roslaun run.launch

在这里插入图片描述
此时,通过map_server 保存该栅格地图</

<think>好的,我现在需要帮助用户解决如何从PCD文件换为PGM格式时过滤地面点的问题。首先,我要理解用户的具体需求。他们可能在做点云处理,比如机器人导航或自动驾驶中的地面分割,需要生成二维的高度地图PGM),但需要先去除地面点。 接下来,我需要回忆点云处理的基本流程。通常,地面过滤的常用方法有RANSAC、平面拟合、半径滤波等。用户提到的引用中有半径滤波的示例,比如引用[1]中的radiusoutlier.filter,这可能用于去除离群点,但单独用半径滤波可能不足以过滤地面。 用户提供的引用[3]提到PCD格式的结构,尤其是无序点云的处理,这可能影响数据读取方式。换到PGM需要将3D点云投影到2D网格,每个网格单元记录高度信息。但地面点如果不先去除,可能会影响PGM的质量,比如地面高度覆盖了其他物体的高度。 接下来,我需要整理步骤。首先,读取PCD文件,可以使用PCL库。然后进行地面分割,比如使用RANSAC算法拟合平面,提取地面点并移除。之后,将剩余的点云投影到二维网格,生成PGM图像。每个步骤需要对应的代码示例,比如PCL的地面分割和投影方法。 还要考虑用户可能遇到的问题,比如点云是否为有组织格式。引用[2]和[3]提到无序点云的WIDTH和HEIGHT设置,这会影响投影时的网格划分。如果点云是无序的,可能需要先进行 voxel 网格过滤,或者根据X、Y坐标的范围生成固定分辨率的网格。 另外,用户可能需要将处理后的点云保存为PGM,这涉及到将每个网格的高度值换为灰度值。需要注意地面点过滤后,网格中可能没有点,这时候可能需要填充默认值或通过插值处理。 最后,生成相关问题时要围绕用户可能进一步的需求,比如其他地面过滤方法、处理无序点云的注意事项,以及PGM生成时的参数调整。确保引用相关的参考资料,如引用中的半径滤波和点云格式说明。</think>### 点云PCDPGM时地面点过滤方法 #### 1. 地面点过滤原理 地面点过滤需基于几何特征分离地面与非地面点。常用方法包括: - **RANSAC平面拟合**:通过随机采样拟合地面平面模型,提取满足平面方程的点集 - **高度阈值法**:设置Z轴高度阈值直接过滤低点(需已知传感器高度) - **法向量分析**:通过点云法向量方向识别水平面特征 引用示例中使用的半径滤波(radiusoutlier.filter)可用于后续离群点去除[^1] #### 2. 换流程(PCL库实现) ```cpp #include <pcl/io/pcd_io.h> #include <pcl/filters/extract_indices.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/sample_consensus/model_types.h> #include <pcl/segmentation/sac_segmentation.h> // 1. 读取点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile("input.pcd", *cloud); // 2. 地面分割 pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients); pcl::PointIndices::Ptr inliers(new pcl::PointIndices); pcl::SACSegmentation<pcl::PointXYZ> seg; seg.setOptimizeCoefficients(true); seg.setModelType(pcl::SACMODEL_PLANE); seg.setMethodType(pcl::SAC_RANSAC); seg.setDistanceThreshold(0.1); // 地面点距离阈值 seg.setMaxIterations(1000); seg.segment(*inliers, *coefficients); // 3. 提取非地面点 pcl::ExtractIndices<pcl::PointXYZ> extract; extract.setInputCloud(cloud); extract.setIndices(inliers); extract.setNegative(true); // 取反选点 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); extract.filter(*cloud_filtered); // 4. 创建高度图(PGM) const float resolution = 0.1; // 单位:米/像素 Eigen::Vector4f min_pt, max_pt; pcl::getMinMax3D(*cloud_filtered, min_pt, max_pt); int width = (max_pt[0] - min_pt[0]) / resolution; int height = (max_pt[1] - min_pt[1]) / resolution; std::vector<float> grid(width * height, -std::numeric_limits<float>::max()); for (const auto& point : cloud_filtered->points) { int x = (point.x - min_pt[0]) / resolution; int y = (point.y - min_pt[1]) / resolution; if (x >=0 && x < width && y >=0 && y < height) { grid[y * width + x] = std::max(grid[y * width + x], point.z); } } // 5. 保存PGM(需添加文件头) ``` #### 3. 关键参数说明 | 参数 | 作用 | 典型值 | |------|------|--------| | `setDistanceThreshold` | 控制地面点识别精度 | 0.05-0.2m | | `resolution` | 决定PGM图像分辨率 | 0.05-0.5m | | `min_pt/max_pt` | 定义点云空间范围 | 自动计算 | #### 4. 注意事项 1. 对于无序点云(如WIDTH=307200,HEIGHT=1的格式[^2]),需先进行体素滤波降采样 2. PGM格式要求单通道灰度图,建议将高度值线性映射到0-255范围 3. 换后的图像行顺序需注意,PCD的Y轴对应PGM的行坐标[^3]
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值