• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

PointCloud 点云处理方法总结(代码案例版)

人工智能 旧人赋荒年 1449次浏览 0个评论

PointCloud 点云处理方法总结(代码案例版)

  本文将自己在点云处理过程中,遇到的一些常用的具体方法进行总结,不介绍点云数据处理的基本概念,主要是处理过程中的代码总结,以及参考案例。  

1. 点云数据类型转换:

  ROS msg, PCLPointCloud2, PointXYZ三种数据类型之间的转换。   ROS msg to PCLPointCloud2  

const sensor_msgs::PointCloud2ConstPtr& cloud_msg
pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2;
pcl_conversions::toPCL(*cloud_msg, *cloud);

  PCLPointCloud2 to ROS msg  

sensor_msgs::PointCloud2 output;
pcl::PCLPointCloud2 cloud_filtered;
pcl_conversions::moveFromPCL(cloud_filtered, output);

  PointXYZ to PCLPointCloud2  

pcl::PointCloud<pcl::PointXYZ> local_map;
pcl::PCLPointCloud2* local_map_pc2_ptr = new pcl::PCLPointCloud2;
pcl::toPCLPointCloud2(local_map, *local_map_pc2_ptr);

  PCLPointCloud2 to PointXYZ  

pcl::PCLPointCloud2 local_map_pc2;
pcl::fromPCLPointCloud2(local_map_pc2, local_map);

  ROS msg to PointXYZ  

sensor_msgs::PointCloud2 output;
pcl::PointCloud<pcl::PointXYZ> icp_cloud_;
pcl::fromROSMsg(output, icp_cloud_);

  ROS msg to PointXYZ  

sensor_msgs::PointCloud2 output;
pcl::PointCloud<pcl::PointXYZ> icp_cloud_;
pcl::fromROSMsg(output, icp_cloud_);

  PointXYZ to ROS msg  

pcl::toROSMsg(local_map,output);

  pointer to const pointer   特别的,有时需要将指针转为常量指针  

pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2;
pcl::PCLPointCloud2ConstPtr cloudPtr(cloud);

 

2. 降采样点云:

  点云常常占用较多计算资源,为了实时处理,需要进行稀疏化,这里 使用VoxelGrid滤波器进行降采样。  

pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());

//创建滤波器
pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
sor.setInputCloud (cloud);

//设置点云稀疏程度
sor.setLeafSize (0.01f, 0.01f, 0.01f);

//降采样后输出到*cloud_filtered
sor.filter (*cloud_filtered);

  详情见降采样点云Downsampling a PointCloud using a VoxelGrid filter   3. 剪裁点云:   机器人在运行的过程中,会一直采集点云加入到地图中,而那些较远处或者处于机器人后面的部分,通常不会用到,为了加快处理速度,需要对点云进行剪裁。   沿着某一个轴进行裁剪  

pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);

//设置裁剪轴
pass.setFilterFieldName ("z");

//设置裁剪范围
pass.setFilterLimits (0.0, 1.0);

//设置输出
pass.filter (*cloud_filtered);

  那么,裁剪三个轴呢?注意,不能一次设置裁剪三个轴(我测试过程中是这样),需要分成三步   三个轴同时裁剪  

{
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(crop_cloud_ptr);
    *crop_cloud_ptr = crop_cloud_;

    // Crop horizontally
    pass.setFilterFieldName("x");
    pass.setFilterLimits(x_limit_left, x_limit_right);
    pass.filter(crop_cloud_);
}
{
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(crop_cloud_ptr);
    *crop_cloud_ptr = crop_cloud_;

    // Crop vertically
    pass.setFilterFieldName("y");
    pass.setFilterLimits(y_limit_above, y_limit_below);
    pass.filter(crop_cloud_);
}
{
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(crop_cloud_ptr);
    *crop_cloud_ptr = crop_cloud_;

    // Crop depth-wise
    pass.setFilterFieldName("z");
    pass.setFilterLimits(z_limit_behind, z_limit_ahead);
    pass.filter(crop_cloud_);
}

  发现另一个pcl::CropBox可以直接进行裁剪   CropBox裁剪  

pcl::CropBox<pcl::PointXYZRGBA> boxFilter;
boxFilter.setMin(Eigen::Vector4f(minX, minY, minZ, 1.0));
boxFilter.setMax(Eigen::Vector4f(maxX, maxY, maxZ, 1.0));
boxFilter.setInputCloud(body);
boxFilter.filter(*bodyFiltered);

  passthrough滤波器例子 CropBox裁剪函数查询  

4. 迭代最近点法ICP match:

  使用迭代最近点法可以将两个具有相同特征的点云进行配准。  

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(cloud_in);
icp.setInputTarget(cloud_out);
pcl::PointCloud<pcl::PointXYZ> Final;
icp.align(Final);

  迭代最近点使用案例,How to use iterative closest point,How to incrementally register pairs of clouds   5. 随机抽样一致算法Random Sample Consensus:   随机抽样一致算法可以在给定正确数据的情况下,去除点云中的由于错误的测量引起的离群点云数据。

//针对点云cloud,建立随机抽样一致的模型
pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr
model_p (new pcl::SampleConsensusModelPlane<pcl::PointXYZ> (cloud));
pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_p);
ransac.setDistanceThreshold (.01);
ransac.computeModel();

//去除离群点后输出
ransac.getInliers(inliers);

  具体例子见How to use Random Sample Consensus model   相关开源代码推荐   maplab https://github.com/ethz-asl/maplab ethzasl_icp_mapping https://github.com/ethz-asl/ethzasl_icp_mapping libpointmatcher https://github.com/ethz-asl/libpointmatcher


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明PointCloud 点云处理方法总结(代码案例版)
喜欢 (0)

您必须 登录 才能发表评论!

加载中……