前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PCL几种采样方法

PCL几种采样方法

作者头像
点云PCL博主
发布2019-07-31 10:49:57
2.1K0
发布2019-07-31 10:49:57
举报
文章被收录于专栏:点云PCL

(1)下采样 Downsampling

一般下采样是通过构造一个三维体素栅格,然后在每个体素内用体素内的所有点的重心近似显示体素中的其他点,这样体素内所有点就用一个重心点来表示,进行下采样的来达到滤波的效果,这样就大大的减少了数据量,特别是在配准,曲面重建等工作之前作为预处理,可以很好的提高程序的运行速度,

代码语言:javascript
复制
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
int main(int argc, char** argv)
{    // 创建点云对象
   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
   pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);    // 读取PCD文件
   if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
   {        return -1;
   }    
// 创建滤波对象
   pcl::VoxelGrid<pcl::PointXYZ> filter;
   filter.setInputCloud(cloud);    // 设置体素栅格的大小为 1x1x1cm
   filter.setLeafSize(0.01f, 0.01f, 0.01f);
   filter.filter(*filteredCloud);
}

实验结果(略)

(2)

均匀采样:这个类基本上是相同的,但它输出的点云索引是选择的关键点在计算描述子的常见方式。

代码语言:javascript
复制
#include <pcl/io/pcd_io.h>
#include <pcl/keypoints/uniform_sampling.h>
int main(int argc, char** argv)
{
   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
   pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);
   if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
   {        return -1;
   }    
// Uniform sampling object.    pcl::UniformSampling<pcl::PointXYZ> filter;
   filter.setInputCloud(cloud);
   filter.setRadiusSearch(0.01f);    
// We need an additional object to store the indices of surviving points.
   pcl::PointCloud<int> keypointIndices;   filter.compute(keypointIndices);
   pcl::copyPointCloud(*cloud, keypointIndices.points, *filteredCloud);
}

(3)增采样 :增采样是一种表面重建方法,当你有比你想象的要少的点云数据时,增采样可以帮你恢复原有的表面(S),通过内插你目前拥有的点云数据,这是一个复杂的猜想假设的过程。所以构建的结果不会百分之一百准确,但有时它是一种可选择的方案。所以,在你的点云云进行下采样时,一定要保存一份原始数据!

代码语言:javascript
复制
#include <pcl/io/pcd_io.h>
#include <pcl/surface/mls.h>
int main(int argc,char** argv)
{// 新建点云存储对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);   
 // 读取文件
   if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
   {        return -1;
   }   
 // 滤波对象
pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> filter;
   filter.setInputCloud(cloud);    //建立搜索对象
   pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;
   filter.setSearchMethod(kdtree);    //设置搜索邻域的半径为3cm
   filter.setSearchRadius(0.03);    
// Upsampling 采样的方法有 DISTINCT_CLOUD, RANDOM_UNIFORM_DENSITY
   filter.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);    // 采样的半径是
   filter.setUpsamplingRadius(0.03);    // 采样步数的大小
   filter.setUpsamplingStepSize(0.02);   filter.process(*filteredCloud);
}

实验的结果

原始图像可视化:

(4)表面重建

深度传感器的测量是不准确的,和由此产生的点云也是存在的测量误差,比如离群点,孔等表面,可以用一个算法重建表面,遍历所有的点云和插值数据,试图重建原来的表面。比如增采样,PCL使用MLS算法和类。执行这一步是很重要的,因为由此产生的点云的法线将更准确。

代码语言:javascript
复制
#include <pcl/io/pcd_io.h>
#include <pcl/surface/mls.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>
int main(int argc, char** argv)
{
   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);    
   pcl::PointCloud<pcl::PointNormal>::Ptr smoothedCloud(new pcl::PointCloud<pcl::PointNormal>);    
if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) != 0)
   {        return -1;
   }    
// Smoothing object (we choose what point types we want as input and output).
   pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> filter;
   filter.setInputCloud(cloud);    // Use all neighbors in a radius of 3cm.
   filter.setSearchRadius(0.03);    // If true, the surface and normal are approximated using a polynomial estimation    
// (if false, only a tangent one).
   filter.setPolynomialFit(true);    
// We can tell the algorithm to also compute smoothed normals (optional).
   filter.setComputeNormals(true);   
// kd-tree object for performing searches.
   pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;
   filter.setSearchMethod(kdtree);
   filter.process(*smoothedCloud); boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("smooth"));
viewer->addPointCloud<pcl::PointNormal>(smoothedCloud,"smoothed");while(!viewer->wasStopped())
 {
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(1000000));
}
}

运行即可查看结果

原始图像(加了颜色)

增采样平滑后(没有颜色信息)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 点云PCL 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档