简体   繁体   中英

PCL: Visualize a point cloud

I'm trying to visualize a point cloud using PCL CloudViewer. The problem is that I'm quite new to C++ and I have found two tutorials first demonstrating the creation of PointCloud and second demonstrating the visualization of a PointCloud. However, I'm not able to combine these two tutorials.

Here is what I have come up with:

#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>

int main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ> cloud;
  
  // Fill in the cloud data
  cloud.width    = 5;
  cloud.height   = 1;
  cloud.is_dense = false;
  cloud.points.resize (cloud.width * cloud.height);

  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    cloud.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
  viewer.showCloud (cloud);

  while (!viewer.wasStopped ())
  {
  }

  return (0);
}

but that even do not compile:

error: no matching function for call to   
‘pcl::visualization::CloudViewer::showCloud(pcl::PointCloud<pcl::PointXYZ>&)’

Your error message tells you what you need to do:

error: no matching function for call to ‘pcl::visualization::CloudViewer::showCloud(pcl::PointCloud<pcl::PointXYZ>&)’

So go to the documentation for CloudViewer and see what arguments this member function takes: http://docs.pointclouds.org/1.5.1/classpcl_1_1visualization_1_1_cloud_viewer.html

There we see that it takes a const MonochromeCloud::ConstPtr &cloud not the raw reference that you are passing in. This is a typedef of a smart pointer from boost:

typedef boost::shared_ptr<const PointCloud<PointT> > pcl::PointCloud< PointT >::ConstPtr

So when you create your cloud you need to wrap it in one of these smart pointers instead of making it a local variable. Something like (untested):

pcl::MonochromeCloud::ConstPtr cloud(new pcl::PointCloud<pcl::PointXYZ>());

Then, when you pass in the variable cloud, it will have the correct type and you won't get the error that you report. You will also have to change your cloud.foo s to cloud->foo s.

Looking at the second example you give, they do this as well:

pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);

To give the answer straight away:

pcl::PointCloud<pcl::PointXYZRGB>::Ptr ptrCloud(&cloud);

Then put in ptrCloud in the viewer, it's what it expects:

viewer.showCloud (ptrCloud);

If anybody else is just searching how to do this in ROS it can be simply done using:

#include <ros/ros.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <iostream>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>

typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;

class cloudHandler
{
public:
    cloudHandler():viewer("Cloud Viewer")
    {
        pcl_sub = nh.subscribe("/camera/depth_registered/points", 10, &cloudHandler::cloudCB, this);
        viewer_timer = nh.createTimer(ros::Duration(0.1), &cloudHandler::timerCB,this);
    }

    void cloudCB(const sensor_msgs::PointCloud2 &input)
    {
        pcl::PointCloud<pcl::PointXYZRGB> cloud;
        pcl::fromROSMsg (input, cloud);
        viewer.showCloud(cloud.makeShared());
    }

    void timerCB(const ros::TimerEvent&)
    {
        if(viewer.wasStopped())
            {
                ros::shutdown();
            }
    }

protected:
    ros::NodeHandle nh;
    ros::Subscriber pcl_sub;
    pcl::visualization::CloudViewer viewer;
    ros::Timer viewer_timer;    
};

int main(int argc, char** argv)
{
    ros::init(argc, argv, "pcl_visualize");
    cloudHandler handler;
    ros::spin();
    return 0;
}

The includes could probably be cleaned more :)

The tutorial for CloudViewer pcl cloudviewer tutorial http://pointclouds.org/documentation/tutorials/cloud_viewer.php#cloud-viewer defines the point cloud as follows:

pcl::PointCloud<pcl::PointXYZRGB>**::Ptr** cloud;

But you have written:

pcl::PointCloud<pcl::PointXYZ> cloud;

So try passing the cloud as &cloud instead of cloud, or declare it as a pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM