You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于pcl_ros去除PointCloud2地面点云的编译报错及可视化问询

自定义PCL点类型编译错误修复与点云可视化实现

一、编译错误修复

错误核心原因

出现‘pcl::PointCloud<VelodynePointXYZIRT>::Ptr’ has no member named ‘makeShared’错误有两个关键问题:

  1. cloud本身已是boost::shared_ptr<pcl::PointCloud<VelodynePointXYZIRT>>类型,makeShared()是pcl::PointCloud类的成员函数,并非智能指针的成员,直接调用会触发报错。
  2. 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可视化(推荐)

  1. 编译运行节点后,启动RViz:
    rosrun rviz rviz
    
  2. 添加可视化组件:
    • 点击左侧面板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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:50:20