PCL: Visualize a point cloud
Asked Answered
R

4

11

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>&)’
Rodger answered 11/4, 2012 at 12:52 Comment(1)
I am doing something similar. Just wanted to know if you were finally able to resolve your errors and build your project ?Overlook
A
10

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>);
Amarillis answered 11/4, 2012 at 13:27 Comment(0)
C
9

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);
Corridor answered 1/2, 2014 at 23:25 Comment(0)
A
1

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 :)

Arthrospore answered 23/1, 2017 at 19:39 Comment(0)
S
0

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.

Sutherlan answered 4/8, 2013 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.