2016-04-03 492 views
3

我很困惑與何時使用pcl::PointCloud2 VS pcl::PointCloudPointCloudPCL :: PCLPointCloud2使用

例如,使用這些定義爲pcl1_ptrApcl1_ptrBpcl1_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 

我可以調用下面的PCL功能:

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

但是,如果我改用pcl::PCLPointCloud2對象,例如:

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

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

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

此功能:

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

vox.setInputCloud(pcl2_ptrA); 

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

vox.filter(*pcl2_ptrB); 

但這些甚至不編譯:

//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); 

我無法發現它的功能接受哪些對象。理想情況下,不是所有PCL函數都會接受pcl::PCLPointCloud2參數嗎?

回答

1

pcl::PCLPointCloud2是ROS(機器人操作系統)消息類型,取代舊的sensors_msgs::PointCloud2。因此,它只能在與ROS進行交互時使用。 (見示例here

如果需要,PCL提供了兩個函數轉換從一種類型到另:

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

額外信息

fromPCLPointCloud2toPCLPointCloud2是用於轉化PCL庫函數。 ROS有pcl_conversions/pcl_conversions.h這些功能的包裝,您應該使用。這些將調用正確的函數組合來在消息和模板格式之間進行轉換。

1

作爲Albert所說的For ROS Hydro and later (if you are using ROS)的後續工作,PCL已經完成了從ROS中刪除所有依賴項的工作。這意味着pcl已經創建了一組類,這些類與相應的ROS消息幾乎相同,以最大限度地減少pcl用戶的API損壞。點雲的用戶使用"now depracated" sensor_msgs::PointCloud2現在要求用pcl_conversions包,這個包實現轉換from/to sensor_msgs::PointCloud2 to/from) pcl::PointCloud並應包括:

#include <pcl_conversions/pcl_conversions.h> 

和ROS代碼應修改爲以下幾點:

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

而且,PCL是不再由ROS社區打包爲一個catkin包,所以任何直接依賴於pcl的包都應該使用新的rosdep規則libpcl-all和libpcl-all-dev,並遵循PCL開發人員在您的CMake中使用PCL的指導原則。通常,這意味着一個package.xml中會喜歡這種改變:

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

更多關於遷移規律可尋hereherehere