(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Turning a PointCloud into an Image

Description: This tutorial is a simple guide to turning a dense point cloud into an image message

Keywords: kinect, pcl, opencv, openni

Tutorial Level: BEGINNER

Use ROS

Let's assume you have an openni camera up and running. Fire up a terminal.

$rostopic list
/camera/depth/points2
/camera/rgb/camera_info
/camera/rgb/image_color
/camera/rgb/image_mono

To convert the point cloud to an image, just run the following

rosrun pcl_ros convert_pointcloud_to_image input:=/camera/depth/points2 output:=/camera/depth/cloud_image

Then subscribe to the image and display it

rosrun image_view image_view image:=/camera/depth/cloud_image

Concept

Given a dense cloud, you can efficiently grab the rgb image from it as a sensor_msgs::Image. The image message can then either be republished or turned into an opencv cv::Mat using standard methods

   1 //pcl::toROSMsg
   2 #include <pcl/io/pcd_io.h>
   3 //...
   4     try
   5     {
   6       pcl::toROSMsg (*cloud, image_); //convert the cloud
   7     }
   8     catch (std::runtime_error)
   9     {
  10     }

You may pass either pcl::PointCloud<PointT>, or a sensor_msgs::PointCloud2.

Code

See the pcl_ros/src/tools/convert_pointcloud_to_image and pcl_ros/src/tools/convert_pcd_to_image for example code.

   1 // ROS core
   2 #include <ros/ros.h>
   3 //Image message
   4 #include <sensor_msgs/Image.h>
   5 //pcl::toROSMsg
   6 #include <pcl/io/pcd_io.h>
   7 //stl stuff
   8 #include <string>
   9 
  10 class PointCloudToImage
  11 {
  12 public:
  13   void
  14   cloud_cb (const sensor_msgs::PointCloud2ConstPtr& cloud)
  15   {
  16     if ((cloud->width * cloud->height) == 0)
  17       return; //return if the cloud is not dense!
  18     try
  19     {
  20       pcl::toROSMsg (*cloud, image_); //convert the cloud
  21     }
  22     catch (std::runtime_error e)
  23     {
  24       ROS_ERROR_STREAM("Error in converting cloud to image message: "
  25                         << e.what());
  26     }
  27     image_pub_.publish (image_); //publish our cloud image
  28   }
  29   PointCloudToImage () : cloud_topic_("input"),image_topic_("output")
  30   {
  31     sub_ = nh_.subscribe (cloud_topic_, 30,
  32                           &PointCloudToImage::cloud_cb, this);
  33     image_pub_ = nh_.advertise<sensor_msgs::Image> (image_topic_, 30);
  34 
  35     //print some info about the node
  36     std::string r_ct = nh_.resolveName (cloud_topic_);
  37     std::string r_it = nh_.resolveName (image_topic_);
  38     ROS_INFO_STREAM("Listening for incoming data on topic " << r_ct );
  39     ROS_INFO_STREAM("Publishing image on topic " << r_it );
  40   }
  41 private:
  42   ros::NodeHandle nh_;
  43   sensor_msgs::Image image_; //cache the image message
  44   std::string cloud_topic_; //default input
  45   std::string image_topic_; //default output
  46   ros::Subscriber sub_; //cloud subscriber
  47   ros::Publisher image_pub_; //image message publisher
  48 };
  49 
  50 int
  51 main (int argc, char **argv)
  52 {
  53   ros::init (argc, argv, "convert_pointcloud_to_image");
  54   PointCloudToImage pci; //this loads up the node
  55   ros::spin (); //where she stops nobody knows
  56   return 0;
  57 }

Wiki: pcl_ros/Tutorials/CloudToImage (last edited 2011-02-04 22:21:41 by ethanrublee)