PCL几种采样方法
(1)下采样 Downsampling
一般下采样是通过构造一个三维体素栅格,然后在每个体素内用体素内的所有点的重心近似显示体素中的其他点,这样体素内所有点就用一个重心点来表示,进行下采样的来达到滤波的效果,这样就大大的减少了数据量,特别是在配准,曲面重建等工作之前作为预处理,可以很好的提高程序的运行速度,
#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[], *cloud) != )
{
return -;
} // 创建滤波对象
pcl::VoxelGrid<pcl::PointXYZ> filter;
filter.setInputCloud(cloud);
// 设置体素栅格的大小为 1x1x1cm
filter.setLeafSize(0.01f, 0.01f, 0.01f);
filter.filter(*filteredCloud);
}
实验结果(略)
(2)
均匀采样:这个类基本上是相同的,但它输出的点云索引是选择的关键点在计算描述子的常见方式。
#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[], *cloud) != )
{
return -;
}
// 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),通过内插你目前拥有的点云数据,这是一个复杂的猜想假设的过程。所以构建的结果不会百分之一百准确,但有时它是一种可选择的方案。所以,在你的点云云进行下采样时,一定要保存一份原始数据!
#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[], *cloud) != )
{
return -;
}
// 滤波对象
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算法和类。执行这一步是很重要的,因为由此产生的点云的法线将更准确。
#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[], *cloud) != )
{
return -;
} // 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();
boost::this_thread::sleep(boost::posix_time::microseconds());
}
}
运行即可查看结果
原始图像(加了颜色)
增采样平滑后(没有颜色信息)
微信公众号号可扫描二维码一起共同学习交流
PCL几种采样方法的更多相关文章
- MLE、MAP、贝叶斯三种估计框架
三个不同的估计框架. MLE最大似然估计:根据训练数据,选取最优模型,预测.观测值D,training data:先验为P(θ). MAP最大后验估计:后验概率. Bayesian贝叶斯估计:综合模型 ...
- 蒙特卡洛马尔科夫链(MCMC)
蒙特卡洛马尔科夫链(MCMC) 标签: 机器学习重要性采样MCMC蒙特卡洛 2016-12-30 20:34 3299人阅读 评论(0) 收藏 举报 分类: 数据挖掘与机器学习(41) 版权声明: ...
- BRIEF 特征描述子
Binary Robust Independent Elementary Features www.cnblogs.com/ronny 1. BRIEF的基本原理 我们已经知道SIFT特征采用了128 ...
- hadoop 数据采样
http://www.cnblogs.com/xuxm2007/archive/2012/03/04/2379143.html 原文地址如上: 关于Hadoop中的采样器 .为什么要使用采样器 在这个 ...
- Hadoop的partitioner、全排序
按数值排序 示例:按气温字段对天气数据集排序问题:不能将气温视为Text对象并以字典顺序排序正统做法:用顺序文件存储数据,其IntWritable键代表气温,其Text值就是数据行常用简单做法:首先, ...
- Mapreduce-Partition分析
Partition所处的位置 Partition位置 Partition主要作用就是将map的结果发送到相应的reduce.这就对partition有两个要求: 1)均衡负载,尽量的将工作均匀的分配给 ...
- Hadoop 的 TotalOrderPartitioner
Partition所处的位置 Partition位置 Partition主要作用就是将map的结果发送到相应的reduce.这就对partition有两个要求: 1)均衡负载,尽量的将工作均匀的分配给 ...
- 第十六节、特征描述符BRIEF(附源码)
我们已经知道SIFT算法采用128维的特征描述子,由于描述子用的是浮点数,所以它将会占用512字节的空间.类似的SUFR算法,一般采用64维的描述子,它将占用256字节的空间.如果一幅图像中有1000 ...
- AD7729_双通道Sigma-Delta ADC
sigma-delta adc的原理,就是通过一种结构把量化噪声调制到频谱的高端,也即对量化噪声而言,sdm是一个高通滤波器,而对基带信号则等价为一个全通滤波器,这样等价的基带信号的量化噪声就很小了, ...
随机推荐
- JavaScript 循环:如何处理 async/await
如何串行或者并行运行异步循环? 在使用循环处理异步的魔法之前,我们先来看下我们是怎么处理同步循环的. 同步循环 很久以前我写的循环是这样的: for (var i = 0; i < array. ...
- unity, shader, Tags的位置
Tags写在Pass里,是不对的,比如: 结果一看shader的Inspector面板,Render queue的值居然不是3001,而是2000: 改为: 再看shader的inspector面板, ...
- rocketMq排坑:如何设置rocketMq broker的ip地址
在工作中遇到了一个这个问题,就是我们rocketmq是部署在云主机上的 但是我们的开发同事在自己的电脑连接rocketmq链接不上 报错显示Caused by: org.apache.rocketmq ...
- Android 3.0开始引入fragments(碎片、片段)类
Fragment要点 Fragment作为Activity界面的一部分组成出现. 可以在一个Activity中同时出现多个Fragment,并且,一个Fragment亦可在多个Activity中使用. ...
- 如何指定一个和你的Android应用程序相适配的屏幕配置
原文:http://android.eoe.cn/topic/android_sdk 描述: 指定每个与该应用程序兼容的屏幕配置.一个配置清单中只能有一个标签的实例,但是它能够包含多个元素.每个元素指 ...
- SQLMap 学习
注入完整流程:http://mp.weixin.qq.com/s/G_DUUVuPH9DeWagjELCPfA sqlmap命令:http://www.cnblogs.com/handt/p/855f ...
- Spring Boot 2.0 利用 Spring Security 实现简单的OAuth2.0认证方式1
0. 前言 之前帐号认证用过自己写的进行匹配,现在要学会使用标准了.准备了解和使用这个OAuth2.0协议. 1. 配置 1.1 配置pom.xml 有些可能会用不到,我把我项目中用到的所有包都贴出来 ...
- .NET微信扫码支付模式二API接口开发测试
主要实现微信扫码支付,官网的SDKdemo 就不要使用 一直不能调试通过的,还是自己按照API接口文档一步一步来实现,吐槽下微信一点责任感都木有,能不能demo搞个正常的吗,不要坑惨了一大群码农们有点 ...
- vim学习笔记(10):vim命令大全
进入vim的命令: vim filename :打开或新建文件,并将光标置于第一行首 vim +n filename :打开文件,并将光标置于第n行首 vim + filename :打开文件,并将光 ...
- Lua语法基础(3)--迭代器和泛型for
迭代器和闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功 ...