Pergunta

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>&)’
Foi útil?

Solução

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.foos to cloud->foos.

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

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

Outras dicas

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 tutorialhttp://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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top