4

Preface: I'm fairly new to coding. Using Ubuntu 12.04 with latest PCL downloaded from their site (I believe PCL 1.7) I've successfully compiled and built the iograbber program listed here: http://pointclouds.org/documentation/tutorials/openni_grabber.php

I've looked up and down through the tutorials on pointclouds.org and there's nothing in there that explains how to add a few lines of code to save the current Kinect point cloud as a PCD file. In the "writer" tutorial it says

pcl::io::savePCDFileASCII ("test_pcd.pcd", cloud)

But this is simply to save the random example points. I want to execute the PCD saving with a keystroke, like pressing the spacebar. I know people have done this before but I cannot find example code. Can anyone point me in the right direction?

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
athoesen
  • 63
  • 2
  • 4

3 Answers3

2

Using the same tutorial, you can add in

 void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
 {
   if (!viewer.wasStopped())
     viewer.showCloud (cloud);
 }

The line you wrote before, in the callback (function that receives the point cloud from the grabber), to have the following

 void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
 {
   if (!viewer.wasStopped()){
     viewer.showCloud (cloud);
     pcl::io::savePCDFile ("test_pcd.pcd", cloud);
   }
 }

This code should save the cloud that you are visualizing. If you are not visualizing the point clouds leave a comment please.

Note: you may also use

pcl::io::savePCDFile ("test_pcd.pcd", cloud, true);

to save in binary mode that is a lot faster (but you may not read the file in text editors)

Hope this helps

api55
  • 11,070
  • 4
  • 41
  • 57
  • you mean `pcl::io::savePCDFileBinary` to save in binary mode, right? – Simson May 21 '14 at 06:35
  • @Simson sorry, I confused the name of the function I use. I edited the answer with the correct function. The last value default is false, and saves as ascii, if true saves as binary. – api55 May 21 '14 at 09:43
  • But how do I decide *when* it saves the cloud? I've seen other example programs where it saves it with a keystroke. How might I do that? – athoesen May 29 '14 at 19:35
  • yes, it is possible though you need to bind the key callback function if you are using pcl grabbers or if you are using openni directly you can just use any c++ key grabbing function and create your own key callback function, if you are displaying it with opencv as a mat you may try to use the waitKey function (this last one you may see an example [here](https://github.com/cvlabbonn/tools_openni2). hope it helps, if not open a new question and I will answer it with more examples and more complete. – api55 May 30 '14 at 10:10
  • @Shashwat you can create a pcd file every time you create the images, but beware... this will reduce the FPS drastically since it has to write it to the hard drive. What I recommend is to save it in memory and then to disk (if your memory is huge enough) or save only the images (depth and rgb) and later on combine them in a pcd file. – api55 Sep 30 '14 at 13:55
  • @api55 Do you also know how to do a recording of a given number of frames with PCL ? – tauseef_CuriousGuy Jun 11 '18 at 08:12
  • @tauseef_CuriousGuy You should write a question to have a more complete answer to that :) but yes, you can add a keyboard callback, let's say that every time you hit s, saves 100 images, you need to just do a counter that increases evertime you save an image until it reaches 100 and restarts every time you hit s – api55 Jun 11 '18 at 09:44
2

This is an ideal solution for anyone working on ROS. So I divided the solution into two parts - one, storing it as ROS bag files (a handy tool for storing any kind of data from ros topics) and two, writing rosbag files to pcd files. This is really simple now.

(References: http://wiki.ros.org/Bags)

A) STORING DATA in BAG files. (ROS file type)

First store the data (any kind of data can be stored) as ROSBAG. ROSBAG just records data from topics.

1.To start using kinect, open a terminal and run

 $roslaunch kinect2_bridge kinect2_bridge.launch publish_tf:=true

This will let ROS system start getting data from kinect. You should see the system starts and stops with "waiting for clients to connect".

2.To view the point cloud, open a new terminal. Run

$ rosrun kinect2_viewer kinect2_viewer sd cloud

And you will see a new window pop up with a point cloud view. Here's link explaining the parameters for kinect2_viewer function: https://github.com/code-iai/iai_kinect2/tree/master/kinect2_viewer

3.To record the data,in a new terminal run

$ rosbag record -O pcl_sample1.bag -a 

Here "-a" means you will subscribe to all available ros topics and record data from them. After you think the data is enough you can stop it by ctrl-C. The data will be stored in a .bag file, here name.bag. More settings can be found here:http://wiki.ros.org/rosbag/Commandline#record

Now unplug kinect. The bag file has data of all the topics which were run by launching kinect2_bridge. Now you can use the data from topics as if kinect was actually plugged in.

4.To play back the data, you need to stop the program in the first terminal (the launch file). Then you run

$ roscore

This will start a ROS server. Then in the other terminal, run

  1. Play the bag file:

    $ rosbag play pcl_sample1.bag

This will let ROS system play back the data you just recorded as if the device is still working. You can then use kinect2_viewer to see the data i.e.:

  1. Run any commands Kinect was actually plugged in.

    $ rosrun kinect2_viewer kinect2_viewer sd cloud

Note: If you want to record specific topics, visit http://wiki.ros.org/Bags.

B) CONVERTING BAG TO PCD Files: (It is just one command now.)

Writing appropriate topics to respective folders:

rosrun pcl_ros bag_to_pcd pcl_sample1.bag /kinect2/sd/image_color_rect src/

rosrun pcl_ros bag_to_pcd pcl_sample1.bag /kinect2/sd/image_depth_rect src/PCD\ Files/
-1

i had the same problem, but i got a solution.

In this code:

     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
 {
   if (!viewer.wasStopped())
     viewer.showCloud (cloud);
 }

You have to add this line

pcl::io::savePCDFileASCII ("test_pcd.pcd", *cloud);

like this

 void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
 {
   if (!viewer.wasStopped())
   {
       viewer.showCloud (cloud);
       pcl::io::savePCDFileASCII ("test_pcd.pcd", *cloud);
   }
 }

It will slow the .exe, but you can try to put thi line in other part in the program