随着工业自动化、智能化的不断推进,机器视觉(2D/3D)在工业领域的应用和重要程度也同步激增(识别、定位、抓取、测量,缺陷检测等),而针对不同作业场景进行解决方案设计时,通常会借助PCL、OpenCV、Eigen等简单方便的开源算法库进行方案的快速验证和迭代以满足作业场景下的目标需求。

基于其算法原理,会将法向相似甚至一致的点数据进行大批量降采样,同时尽可能保留法向特征较为“明显”位置的点云数据

/** @File: normal_space_sample.cpp* @Brief: pcl course* @Description: 展示NSS法向空间采样效果*/
#include <iostream>
#include <string>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/normal_space.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/visualization/pcl_visualizer.h>int main(int argc, char** argv){if(argc != 2){std::cout<<"Usage: exec cloud_file_path"<<std::endl;return -1;}const std::string kCloudFilePath = argv[1]; // ../clouds/cabinet/cabinet_color_cloud.pcd// 定义变量pcl::PointCloud<pcl::PointXYZ>::Ptr \cloud_src(new pcl::PointCloud<pcl::PointXYZ>());pcl::PointCloud<pcl::Normal>::Ptr \cloud_normals(new pcl::PointCloud<pcl::Normal>());// 成功返回0,失败返回-1if(-1 == pcl::io::loadPCDFile(kCloudFilePath,*cloud_src)){std::cout<<"load pcd file failed. please check it."<<std::endl;return -2;}// 创建基于邻域的法向估计类对象// // 基于omp并行加速,需配置开启OpenMP// pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne; // ne.setNumberOfThreads(10);pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;// 创建一个空的kdtree对象,并把它传递给法线估计对象,// 用于创建基于输入点云数据的邻域搜索kdtreepcl::search::KdTree<pcl::PointXYZ>::Ptr \tree(new pcl::search::KdTree<pcl::PointXYZ>());// 传入待估计法线的点云数据,智能指针ne.setInputCloud(cloud_src);// 传入kdtree对象,智能指针ne.setSearchMethod(tree);// 设置邻域搜索半径ne.setRadiusSearch(0.1f);    // 设置半径时,要考虑到点云空间间距// // 也可以设置最近邻点个数// ne.setKSearch(25);// 设置视点源点,用于调整点云法向(指向视点),默认(0,0,0)ne.setViewPoint(0,0,0);// 计算法线数据ne.compute(*cloud_normals);// 通过concatenateFields函数将point和normal组合起来形成PointNormal点云数据pcl::PointCloud<pcl::PointNormal>::Ptr \cloud_with_normal(new pcl::PointCloud<pcl::PointNormal>());pcl::PointCloud<pcl::PointNormal>::Ptr \cloud_with_normal_sampled(new pcl::PointCloud<pcl::PointNormal>());pcl::concatenateFields(*cloud_src, *cloud_normals, *cloud_with_normal);// 创建法向空间采样(模板)类对象pcl::NormalSpaceSampling<pcl::PointNormal, pcl::Normal> nss;// 设置xyz三个法向空间的分类组数,此处设置为一致,根据具体场景可以调整const int kBinNum = 8;nss.setBins(kBinNum, kBinNum, kBinNum);// 如果传入的是有序点云,此处可以尝试设置为truenss.setKeepOrganized(false);// 设置随机种子,这样可以保证同样的输入可以得到同样的结果,便于debug分析nss.setSeed(200);   // random seed// 传入待采样的点云数据nss.setInputCloud(cloud_with_normal);// 传入用于采样分析的法线数据,需与传入点云数据一一对应nss.setNormals(cloud_normals);// 设置采样总数,即目标点云的总数据量const float kSampleRatio = 0.1f;nss.setSample(cloud_with_normal->size()*kSampleRatio);// 执行采样并带出采样结果nss.filter(*cloud_with_normal_sampled);// 创建可视化对象pcl::visualization::PCLVisualizer viewer("viewer");// 将当前窗口,拆分成横向的2个可视化窗口,以viewport区分(v1/v2)int v1; int v2;//窗口参数分别对应 x_min, y_min, x_max, y_max, viewportviewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);  viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 添加2d文字标签viewer.addText("v1", 10,10, 20, 1,0,0, "viewport_v1", v1);viewer.addText("v2", 10,10, 20, 0,1,0, "viewport_v2", v2);// 添加坐标系viewer.addCoordinateSystem(0.5);    // 单位:m// 设置可视化窗口背景色viewer.setBackgroundColor(0.2,0.2,0.2);     // r,g,b  0~1之间// 向v1窗口中添加点云viewer.addPointCloud(cloud_src,"cloud_src",v1);// 设置单一颜色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointNormal> color(cloud_with_normal_sampled, 255, 0, 0);// 向v2窗口中添加点云viewer.addPointCloud<pcl::PointNormal>(cloud_with_normal_sampled,color,"cloud_sampled",v2);// 根据点云id,设置点云可视化属性,此处将可视化窗口中的点大小调整为2级// viewer.setPointCloudRenderingProperties \ //      (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud_sampled");// // 向v2窗口中添加法线可视化// viewer.addPointCloudNormals<pcl::PointNormal, pcl::PointNormal> \//         (cloud_with_normal_sampled, cloud_with_normal_sampled, \//         1, 0.02, "cloud_normals", v2);// 关闭窗口则退出while(!viewer.wasStopped()){viewer.spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return 0;
}

展示NormalSpaceSampling(NSS)法向空间降采样效果:

UniformSampling均匀降采样

基于均匀概率分布进行采样,达到降低数据量的目的;
相比于VoxelGrid体素栅格采样,VoxelGrid能够在保证点云几何特征不变的条件下,控制点云空间间距,工程中使用的更多一些;

/** @File: uniform_sample.cpp* @Brief: pcl course* @Description: 展示UniformSample均匀采样效果*/
#include <iostream>
#include <string>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/uniform_sampling.h>
#include <pcl/visualization/pcl_visualizer.h>int main(int argc, char** argv){if(argc != 2){std::cout<<"Usage: exec cloud_file_path"<<std::endl;return -1;}const std::string kCloudFilePath = argv[1];     // ../clouds/cabinet/cabinet_color_cloud.pcd// 定义变量pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_src(new pcl::PointCloud<pcl::PointXYZRGB>());pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>());// 成功返回0,失败返回-1if(-1 == pcl::io::loadPCDFile(kCloudFilePath,*cloud_src)){std::cout<<"load pcd file failed. please check it."<<std::endl;return -2;}// 创建均匀采样(模板)类对象,点数据类型为 pcl::PointXYZRGBpcl::UniformSampling<pcl::PointXYZRGB> us;// 设置输入点云,注意:此处传入的是点云类对象的智能指针us.setInputCloud(cloud_src);// 设置采样半径,数值越大越稀疏us.setRadiusSearch(0.08f);// 执行过滤,并带出处理后的点云数据,注意:此处传入的是点云类对象us.filter(*cloud_filtered);// 创建可视化对象pcl::visualization::PCLVisualizer viewer("viewer");// 将当前窗口,拆分成横向的2个可视化窗口,以viewport区分(v1/v2)int v1; int v2;//窗口参数分别对应 x_min, y_min, x_max, y_max, viewportviewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);  viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 添加2d文字标签viewer.addText("v1", 10,10, 20, 1,0,0, "viewport_v1", v1);viewer.addText("v2", 10,10, 20, 0,1,0, "viewport_v2", v2);// 添加坐标系viewer.addCoordinateSystem(0.5);    // 单位:m// 设置可视化窗口背景色viewer.setBackgroundColor(0.2,0.2,0.2);     // r,g,b  0~1之间// 向v1窗口中添加点云viewer.addPointCloud(cloud_src,"cloud_src",v1);// 根据点云id,设置点云可视化属性,此处将可视化窗口中的点大小调整为2级viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud_src");// 向v2窗口中添加点云viewer.addPointCloud(cloud_filtered,"cloud_filtered",v2);// 根据点云id,设置点云可视化属性,此处将可视化窗口中的点大小调整为2级viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud_filtered");// 关闭窗口则退出while(!viewer.wasStopped()){viewer.spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return 0;
}

参考文献:点云降采样

NormalSpaceSampling 基于法向空间的点云降采样相关推荐

  1. 基于体素化方法的点云降采样

    前两天做了一个点云降采样的项目,用pcl自带的降采样方法出来的结果不是很理想,于是就自己写了一个.为了使代码执行效率高点就采用了基于点云索引的方式. 本文使用的方法为:首先,计算点云群的Boundin ...

  2. 我们成功给OpenCV添加了三维点云降采样算法!

    作者:阮业淳,钟万里,张昌圳(本科生) 指导教师:于仕琪 南方科技大学计算机科学与工程系 知名开源计算机视觉库OpenCV(Open Source Computer Vision Library)在其 ...

  3. 点云降采样(DownSampling)

    点云降采样 1 概述 三维点云往往包含大量冗余数据,直接处理计算量大,消耗时间长,因此对其进行降采样是十分必要的.降采样同时也是点云预处理过程中的关键环节. 2 常用方法 2.1 体素网格下采样 2. ...

  4. 点云降采样--ApproximateVoxelGrid点云降采样

    1.版本要求 版本: >PCL1.0 2.简介 ApproximateVoxelGrid体素降采样是PCL开源库中非常有效的点云降采样手段.ApproximateVoxelGrid对点云进行体素 ...

  5. matlab 降采样代码,matlab 点云降采样 pcdownsample()

    ** 点云数据降采样 pcdownsample() ** pcdownsample降采样减少点云数据量: 一.语法: ptCloudOut = pcdownsample(ptCloudIn, 'ran ...

  6. 无人驾驶汽车系统入门(二十五)——基于欧几里德聚类的激光雷达点云分割及ROS实现

    无人驾驶汽车系统入门(二十五)--基于欧几里德聚类的激光雷达点云分割及ROS实现 上一篇文章中我们介绍了一种基于射线坡度阈值的地面分割方法,并且我们使用pcl_ros实现了一个简单的节点,在完成了点云 ...

  7. PCL点云处理之基于法向差异的图像分割(九十七)

    PCL点云处理之基于法向差异的图像分割(九十七) 一.算法简介 二.使用步骤 1.引入库 2.效果 一.算法简介 使用在pcl::DifferenceOfNormalsEstimation估计类中实现 ...

  8. 基于全景图像与激光点云配准的彩色点云生成算法(2014年文章)

    标题:The algorithm to generate color point-cloud with the registration between panoramic imageand lase ...

  9. PU-Net:一种基于数据的3D点云上采样网络

    点击上方"视学算法",选择"星标" 干货第一时间送达 论文下载: https://openaccess.thecvf.com/content_cvpr_2018 ...

最新文章

  1. 1.1 内存的四个分区
  2. 开源大数据周刊-第30期
  3. Spring Cloud Gateway中异常处理
  4. Machine Learning week 6 quiz: Advice for Applying Machine Learning
  5. chromebook刷机_您可以购买的最好的Chromebook,2017年版
  6. select2删除选中项,allowClear设置
  7. Qt文档阅读笔记-QGraphicsEffect::draw(QPainter *painter)官方解析与实例
  8. 参加第六届中国制造业MES应用年会
  9. editor修改样式 vue_vue修改富文本中的元素样式
  10. access转sql iif_ACCESS 中的IIF使用
  11. 全网通是4g显示无服务器,4G+时代的全网通?可没有那么简单!
  12. SpringMVC拦截器(包括自定以拦截器--实现HandlerInterceptorAdapter)(资源和权限管理)...
  13. 《Adobe Illustrator CC 2014中文版经典教程(彩色版)》—第1课0.19节使用画笔
  14. Java连接数据库访问失败
  15. php好用的中文转拼音的类库
  16. 火星来客创业周刊第1期:独立开发者Twitter小工具60天,从月入300美金到月入3000美金
  17. [linux命令]查找包含指定内容的文件
  18. 浮点数 C语言 IEEE754
  19. 智慧工厂的大脑——APS生产排程系统
  20. 如何最简单、通俗地理解Python的pandas库?

热门文章

  1. 为什么电脑黑屏但是电源是亮的
  2. 为LTO磁带而生的文件系统LTFS|主线任务—夺回“秋雅“
  3. oracle clusterware 11g,Oracle 11gR2 clusterware启动顺序
  4. 957.N天后的牢房
  5. iOS 币行(BTC 、LTC、LTH、ETC) 简介
  6. 嵌入式linux开发,NUC972芯片外设ADC,通过IIO ADC使用自带ADC转换模块,及ADC电池电压检测
  7. 饿了么 EMonitor 演进史
  8. 从文电传输说起(一)
  9. ubuntu下自动安装arm-linux-gcc和arm-linux-g++
  10. Delta lake 与湖仓一体