pcl点云的一些学习认识

版权声明:坚持原创,禁止转载。 https://blog.csdn.net/SLAM_masterFei/article/details/79570825

博主最近在做三维重建,之前就了解过pcl库,俗话说,二维处理靠opencv,三维处理靠pcl,那么这个点云库到底有什么神奇功能呢?博主才疏学浅,现在就学了如何将三维点显示和一些简单的滤波,在这里,对自己,也是对广大初学者都可以做个复习和简单的介绍。

首先如何将已有的三维点显示,博主这里是利用深度相机直接测得的深度,帧之间通过icp获得世界坐标系下的空间位姿,在这里,我们简单来看从深度照片中提取点云。

pcl::pointcloud<pcl::pointxyzrgb>::ptr pointcloud(new pcl::pointcloud<pcl::pointxyzrgb>);
//opencv提取点云
Mat color=imread("your adress");
Mat depth=imread("your adress",-1);
//遍历像素,还原深度和三维点
for(int v=0;v<color.rows;v++)
 for(int u=0;u<color.cols;u++)
  {
     ushort d=depth.ptr<unsigned short>(v)[u];
     //还原三维点
    Point3d world;
    world.z=double(d)/1000.0;
    world.x=(u-cx)/fx*world.z;
    world.y=(v-cy)/fy*world.z;
    //定义点云类型(博主手码,类函数里面一些大小写就不区分了,大家自己写应该一眼就看得出)
    pcl::xyzrgb pc;
    pc.x=world.x;
    pc.y=world.y;
    pc.z=world.z;
    pc.b=color.data[v*color.step+u*color.channels()];
    pc.g=color.data[v*color.step+u*color.channels()+1];
    pc.r=color.data[v*color.step+u*color.channels()+2];
    pointcloud->push_back(pc);
  }
//好了,至此你已经将照片上的像素点都添加到点云了,注意了,博主自己码的,所以类的名称大小写应该都是错的(QAQ),见谅。
pointcloud->is_dense=false;
//将照片保存
pcl::io::savepcdfilebinary("map.pcd",*pointcloud);

博主其实不懒,上面的代码大家将就看吧,对不起大家啊,不能复制黏贴哈哈。

好了,下面介绍两种常见的滤波,统计滤波和体素滤波,博主学的不深,简单来说,统计滤波是将空间上的点聚类,感觉是不是类似kmeans啊哈哈,然后去除孤立的点,一般用来去除带噪声的数据,而体素滤波是将一个很小空间上的点里面很多个点算它们的质心,博主感觉是用来消除重投影误差的把,意思是可能一个点被不同观测重新还原到了有些误差的不同位置,这样可以是整个空间更加趋于平滑,也为以后的稠密重建做好了准备。

废话不多说,博主懒了,直接上代码了,大家讲究看吧,实在不好意思了。

  //统计滤波,存放点云
	  pointcloud::Ptr currentstatistical(new pointcloud);
	  //定义统计滤波类
	  pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> statistical_filter;
	  statistical_filter.setMeanK(50);
	  statistical_filter.setStddevMulThresh(1.0);
	  statistical_filter.setInputCloud(currentpoint);
	  statistical_filter.filter(*currentstatistical);
	  (*pointcloud_ptr)=(*pointcloud_ptr)+(*currentstatistical);

这是统计滤波,大家应该看得懂吧

pcl::VoxelGrid<pcl::PointXYZRGB> voxel_filter;
  //设置最小单位
  voxel_filter.setLeafSize(0.01,0.01,0.01);
  voxel_filter.setInputCloud(pointcloud_ptr);
  //定义点云类型存放滤波后的
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr current_voxelpoint;
  voxel_filter.filter(*current_voxelpoint);
  current_voxelpoint->swap(*pointcloud_ptr);

这是体素滤波,估计问题不大对应各位来说

各位再见

阅读更多
换一批

没有更多推荐了,返回首页