pcl::PCLPointCloud2 usage
Asked Answered
R

2

5

I'm confused with when to use pcl::PointCloud2 vs pcl::PointCloudPointCloud

For example, using these definitions for pcl1_ptrA, pcl1_ptrB and pcl1_ptrC:

pcl::PointCloud<pcl::PointXYZRGB>::Ptr pcl1_ptrA(new pcl::PointCloud<pcl::PointXYZRGB>); //pointer for color version of pointcloud
pcl::PointCloud<pcl::PointXYZRGB>::Ptr pcl1_ptrB(new pcl::PointCloud<pcl::PointXYZRGB>); //ptr to hold filtered Kinect image
pcl::PointCloud<pcl::PointXYZRGB>::Ptr pcl1_ptrC(new pcl::PointCloud<pcl::PointXYZRGB>); //ptr to hold filtered Kinect image

I can invoke the following PCL functions:

pcl::VoxelGrid<pcl::PointXYZRGB> vox;

vox.setInputCloud(pcl1_ptrA); 

vox.setLeafSize(0.02f, 0.02f, 0.02f);

vox.filter(*pcl1_ptrB); 

cout<<"done voxel filtering"<<endl;

cout<<"num bytes in original cloud data = "<<pcl1_ptrA->points.size()<<endl;

cout<<"num bytes in filtered cloud data = "<<pcl1_ptrB->points.size()<<endl; // ->data.size()<<endl; 

Eigen::Vector4f xyz_centroid; 

pcl::compute3DCentroid (*pcl1_ptrB, xyz_centroid);

float curvature;

Eigen::Vector4f plane_parameters;  

pcl::computePointNormal(*pcl1_ptrB, plane_parameters, curvature); //pcl fnc to compute plane fit to point cloud

Eigen::Affine3f A(Eigen::Affine3f::Identity());

pcl::transformPointCloud(*pcl1_ptrB, *pcl1_ptrC, A);    

However, if I instead use pcl::PCLPointCloud2 objects, e.g.:

pcl::PCLPointCloud2::Ptr pcl2_ptrA (new pcl::PCLPointCloud2 ());

pcl::PCLPointCloud2::Ptr pcl2_ptrB (new pcl::PCLPointCloud2 ());

pcl::PCLPointCloud2::Ptr pcl2_ptrC (new pcl::PCLPointCloud2 ());

This function works:

pcl::VoxelGrid<pcl::PCLPointCloud2> vox;

vox.setInputCloud(pcl2_ptrA); 

vox.setLeafSize(0.02f, 0.02f, 0.02f);

vox.filter(*pcl2_ptrB);

But these do not even compile:

//the next 3 functions do NOT compile:

Eigen::Vector4f xyz_centroid; 

pcl::compute3DCentroid (*pcl2_ptrB, xyz_centroid);

float curvature;

Eigen::Vector4f plane_parameters;   

pcl::computePointNormal(*pcl2_ptrB, plane_parameters, curvature); 

Eigen::Affine3f A(Eigen::Affine3f::Identity());

pcl::transformPointCloud(*pcl2_ptrB, *pcl2_ptrC, A);  

I am having trouble discovering which functions accept which objects. Ideally, wouldn't all PCL functions accept pcl::PCLPointCloud2 arguments?

Renferd answered 3/4, 2016 at 0:20 Comment(0)
T
5

pcl::PCLPointCloud2 is a ROS (Robot Operating System) message type replacing the old sensors_msgs::PointCloud2. Hence, it should only be used when interacting with ROS. (see an example here)

If needed, PCL provides two functions to convert from one type to the other:

void fromPCLPointCloud2 (const pcl::PCLPointCloud2& msg, cl::PointCloud<PointT>& cloud);
void toPCLPointCloud2 (const pcl::PointCloud<PointT>& cloud, pcl::PCLPointCloud2& msg);

Extra Information

fromPCLPointCloud2 and toPCLPointCloud2 are PCL library functions for conversions. ROS has wrappers for those functions in pcl_conversions/pcl_conversions.h that you should use instead. These will call the right combinations of functions to convert between the message and templated format.

Tensile answered 4/4, 2016 at 16:36 Comment(0)
O
3

As a follow-up for what Albert said, For ROS Hydro and later (if you are using ROS), PCL has done a work to remove all its dependencies from ROS. What this means is the pcl has created a set of classes which are almost identical to the corresponding ROS messages, in order to minimize API breakage for pcl users. PointCloud users using "now depracated" sensor_msgs::PointCloud2 are now asked to use pcl_conversions package, this package implements conversions from/to sensor_msgs::PointCloud2 to/from) pcl::PointCloud and should include :

#include <pcl_conversions/pcl_conversions.h>

and the ROS code should be modified as the following :

void foo(const sensor_msgs::PointCloud2 &pc)
{
  pcl::PCLPointCloud2 pcl_pc;
  pcl_conversions::toPCL(pc, pcl_pc);
  pcl::SomePCLFunction(pcl_pc);
  ...
}

Also, pcl is no longer packaged by the ROS community as a catkin package, so any packages which directly depend on pcl should instead use the new rosdep rules libpcl-all and libpcl-all-dev and follow the PCL developer's guidelines for using PCL in your CMake. Generally this means that a package.xml will change like this:

find_package(PCL REQUIRED)
...
include_directories(${PCL_INCLUDE_DIRS})
...
target_link_libraries(<YOUR_TARGET> ${PCL_LIBRARIES})

More on the migration rules can be found here, here and here.

Oft answered 5/4, 2016 at 10:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.