基于pcl_ros去除PointCloud2地面点云的编译报错及可视化问询
自定义PCL点类型编译错误修复与点云可视化实现
一、编译错误修复
错误核心原因
出现‘pcl::PointCloud<VelodynePointXYZIRT>::Ptr’ has no member named ‘makeShared’错误有两个关键问题:
cloud本身已是boost::shared_ptr<pcl::PointCloud<VelodynePointXYZIRT>>类型,makeShared()是pcl::PointCloud类的成员函数,并非智能指针的成员,直接调用会触发报错。pcl::SACSegmentation的模板参数应为点类型,而非点云类型,原代码中pcl::SACSegmentation<pcl::PointCloud<PointXYZIRT>>的写法不符合API规范。
修复后的地面去除代码
#include <iostream> #include <cmath> #include <vector> #include <ros/ros.h> #include <sensor_msgs/PointCloud2.h> #include <pcl_ros/point_cloud.h> #include <pcl/point_types.h> #include <pcl_conversions/pcl_conversions.h> #include <velodyne_pointcloud/point_types.h> #include <pcl/common/common.h> #include <pcl/common/centroid.h> #include <pcl/common/transforms.h> #include <pcl/console/parse.h> #include <set> #include <pcl/io/pcd_io.h> #include <boost/format.hpp> #include <pcl/filters/voxel_grid.h> #include <pcl/filters/passthrough.h> #include <pcl/filters/extract_indices.h> #include <pcl/sample_consensus/model_types.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/segmentation/sac_segmentation.h> struct VelodynePointXYZIRT { PCL_ADD_POINT4D PCL_ADD_INTENSITY; uint16_t ring; float time; EIGEN_MAKE_ALIGNED_OPERATOR_NEW } EIGEN_ALIGN16; POINT_CLOUD_REGISTER_POINT_STRUCT (VelodynePointXYZIRT, (float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity) (uint16_t, ring, ring) (float, time, time) ) ros::Publisher pub_ground; ros::Publisher pub_non_ground; using PointXYZIRT = VelodynePointXYZIRT; void cloud_callback(const sensor_msgs::PointCloud2ConstPtr& scan) { // 将ROS点云消息转换为PCL点云 pcl::PointCloud<VelodynePointXYZIRT>::Ptr cloud(new pcl::PointCloud<VelodynePointXYZIRT>()); pcl::fromROSMsg(*scan, *cloud); pcl::ModelCoefficients coefficients; pcl::PointIndices inliers; // 修正SACSegmentation模板参数为点类型 pcl::SACSegmentation<PointXYZIRT> seg; seg.setOptimizeCoefficients(true); seg.setModelType(pcl::SACMODEL_PLANE); seg.setMethodType(pcl::SAC_RANSAC); seg.setDistanceThreshold(0.01); // 直接传入智能指针,无需调用makeShared() seg.setInputCloud(cloud); seg.segment(inliers, coefficients); // 提取地面点与非地面点 pcl::ExtractIndices<PointXYZIRT> extract; pcl::PointCloud<PointXYZIRT>::Ptr cloud_ground(new pcl::PointCloud<PointXYZIRT>()); pcl::PointCloud<PointXYZIRT>::Ptr cloud_non_ground(new pcl::PointCloud<PointXYZIRT>()); extract.setInputCloud(cloud); extract.setIndices(boost::make_shared<pcl::PointIndices>(inliers)); extract.setNegative(false); extract.filter(*cloud_ground); extract.setNegative(true); extract.filter(*cloud_non_ground); // 发布地面点云 sensor_msgs::PointCloud2 output_ground; pcl::toROSMsg(*cloud_ground, output_ground); output_ground.header = scan->header; pub_ground.publish(output_ground); // 发布去地面后的点云 sensor_msgs::PointCloud2 output_non_ground; pcl::toROSMsg(*cloud_non_ground, output_non_ground); output_non_ground.header = scan->header; pub_non_ground.publish(output_non_ground); } int main(int argc, char** argv) { ros::init(argc, argv, "ground_removal_node"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe("input", 1, cloud_callback); pub_ground = nh.advertise<sensor_msgs::PointCloud2>("ground_points", 1); pub_non_ground = nh.advertise<sensor_msgs::PointCloud2>("non_ground_points", 1); ros::spin(); }
二、点云可视化实现
方法1:ROS RViz可视化(推荐)
- 编译运行节点后,启动RViz:
rosrun rviz rviz - 添加可视化组件:
- 点击左侧面板
Add按钮,选择PointCloud2 - 将
Topic设置为节点发布的/non_ground_points或/ground_points - 设置
Fixed Frame为点云对应的坐标系(如velodyne)
- 点击左侧面板
方法2:PCL原生可视化窗口
若需在代码中直接弹出可视化窗口,可添加以下逻辑(需包含PCL可视化头文件):
#include <pcl/visualization/pcl_visualizer.h> #include <boost/thread/thread.hpp> void visualize_cloud(pcl::PointCloud<PointXYZIRT>::Ptr& cloud) { pcl::visualization::PCLVisualizer viewer("PointCloud Viewer"); viewer.setBackgroundColor(0, 0, 0); viewer.addPointCloud<PointXYZIRT>(cloud, "target_cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target_cloud"); while (!viewer.wasStopped()) { viewer.spinOnce(100); boost::this_thread::sleep(boost::posix_time::microseconds(100000)); } }
注:在ROS节点中使用该方法需单独开启线程,避免阻塞ROS消息循环。
内容的提问来源于stack exchange,提问作者lee dida
相关产品推荐
相关产品推荐

