说到点云,就需要提下点云核心处理算法–八叉树

对于八叉树呢,首先可能接触到的就是pcl的八叉树的邻域搜索,短短几句代码就实现了查找邻域的功能,一开始觉得还挺好用的,用久了,会有一个疑问在:八叉树的具体实现机制是什么,网上查了很多资料,都是在说八叉树有多***,似乎很少有关于八叉树的精细讲解,见得最多就是那个八叉树的树状图。。。。。上源码

八叉树长什么样:
在pcl里面写到
typedef pcl::octree::OctreeLeafNode LeafNode;
typedef pcl::octree::OctreeBranchNodeBranchNode;
解析:节点分两种,一个是分支节点,另一个是叶子节点,那些空心的圆球指的就是空节点,八叉树的节点要么8个要么0个(因为有空节点的存在),之所以存在是因为不存在数据点,这样以来就能提高数据遍历的效率

  1. (第一part)分开功能
    八叉树的分层,分几层,也可以指定八叉树的叶子节点(俄罗斯套娃。。。,盒子套盒子,那个最小的盒子)所对应包围盒的大小。你可以理解成盒子里刚刚好填满8个盒子,知道设定的深度位置。
    举个栗子—>如果八叉树的深度为3,先将外包的大盒子分成八个,然后对这8个盒子又分别分成8个,然后再次分成8个。执行3次为止,当然空节点直接跳过。
    深度1的状态:

    深度2的状态:

    深度3的状态:

单从z方向(纵向)这个维度来看,深度每增加一层,在维度上就会一分为二

  1. (第二part)邻域搜索

    流程图如上,其实就是一个迭代的过程,对待每个分支节点重复流程1的操作。
  • 一点包围盒邻域的获取(配合上图进行说明)
    对于邻域搜索的问题呢,还是先举个栗子切入吧,我们求一点包围盒内的邻域点。其思路是:从根节点开始判断,判断每一个根节点是否与所设置的包围盒有交集,如果有继续查找其子节点,同样判断其子节点与该包围盒是否存在交集,直到访问叶子节点,如果该叶子节点与所设置包围盒有交集,便获取该叶子节点里的索引执行判定条件3(对于每个节点的判断无论是分支节点还是叶子节点都会执行一个判定条件,即这里的判定条件1与条件2,这里的条件1与条件2都是2个包围盒是否存在交集)。

流程:

  1. 这里预先设置的包围盒为boundingbox1(即所需获取的索引的包围盒),当前节点的包围盒为boundingbox2。
  2. 判定boundingbox1与boundingbox2是否存在交集,即流程图里的判定条件1与条件2(这里的条件是一致的)
  3. 如果到了叶子节点,且满足b,那么则要执行判定条件3,即判定Pi是否在boundingbox1里
    看效果:
    与包围盒有交集的叶子节点:

包围盒里面的数据点:

整体效果:

  • 一点半径邻域的获取
    求一点半径邻域内的数据点,可以先将球处理成包围盒子,唯一不同的是处理到叶子节点时,判定条件即为两点之间的点间距

和包围盒有交集的叶子节点:

包围盒里的数据点:

整体效果:

  • 一点K邻域的获取

对于k近邻会比较复杂,因为并不知道那些点距离自己最近,而且这些点可能来自于周围的数个叶子节点(多了很可能会乱),所以算法处理一开始只能通过访问到的第一个叶子节点,然后执行以下操作

using namespace std;
。。。。
sort(point_candidates.begin(), point_candidates.end());
if( point_candidates.size() > K ){
point_candidates.resize(K);
}
if( point_candidates.size() == K ){
smallest_squared_dist = point_candidates.back().point_distance_;
}

这就很直观了,升序排序,然后取到第k个值
对于下一个节点就会以smallest_squared_dist作为一个判断依据,总不能所有节点都去访问吧

float disThread = smallest_squared_dist + voxelSquaredDiameter / 4.0 + sqrt(smallest_squared_dist * voxelSquaredDiameter);
if( search_heap.back().point_distance < disThread ){ //满足这个条件
}

voxelSquaredDiameter 代表当前深度节点的包围盒的长度,smallest_squared_dist代表上次叶子节点获取的邻域点里第K个距离值(已经升序排序了,如果没找到K个邻域,那么smallest_squared_dist的值为初始化的值,一般设置较大) search_heap.back().point_distance 代表当前层次的根节点包围盒的中心点与搜索点的距离

当然也是可以理解成这样形式的条件:

 search_heap.back().point_distance - δ<smallest_squared_dist  =>  search_heap.back().point_distance<smallest_squared_dist + δ

K近邻搜索结果

  1. (第三part)一点所在叶子节点的父节点及其兄弟节点
    获取一点所在的叶子节点,然后获取该叶子节点所在的父亲节点,并且获取该叶子节点的兄弟节点==方法(简单概括)如下:
  • 这里定义八叉树的最大深度为 maxDepth,查询点为Pt
  • 那么其父亲节点必定在maxDepth-1层,那么判定条件-----Pt在此层根节点的包围盒内。假设得到该父亲节点且命名为parentNode.
  • 获取parentNode的子节点,判断子节点与Pt的空间关系,包含关系的属于当前节点,否则属于其兄弟节点
    看图:
    红色部分是该节点,剩下是它的兄弟节点

    (再进一步)白色的是父节点:

    整体效果:

Deer计划(2)cloudcompare解析--八叉树相关推荐

  1. Deer计划(1)点云数据解析成图

    第一part 点云数据的解析成图 需要自行配置jsoncpp.OpenCV运行环境 1. 点云数据的解析成图模块设计 测试环境 i5-9400f 16g (测试情况和实机性能有关) 线程解析(以法如的 ...

  2. 【C#串口编程计划】通信协议解析 -- byte[]与常用类型的转换

    刚刚完成一个串口通讯的系统.目前在把串口通信的代码整合到团队的类库中(把串口通信与网口Soket通讯整合起来,后面只需要配置参数,就可实现网络与串口通讯的转换),故C#串口编程计划的最后一篇图文&qu ...

  3. 2019年6月英语四级考试计划和题型解析

    今天是2019年3月26日,距离6月15日的CET4还有80天.如果你不去安排好自己的时间,时间就会悄悄从你指尖流走,从一开学英语老师就已经为我们的第一次四级考试做好计划了,而我,惯有的拖延症,一直拖 ...

  4. SAP-SD计划行类别解析

    计划行类别. 计划行类别的例子Schedule Line categories 系统交付了不同schedule line categories来为Item在销售流程中提供不同的控制选项: schedu ...

  5. P1089津津的储蓄计划-C++编程解析-分支

    解题思路 津津在每个月的月初,会得到妈妈给的固定的300元.加上津津上个月没有花完的钱,就是津津本月初拥有的钱.此时,津津需要根据自己目前所拥有的钱,和本月的预算进行判断.一种情况是,津津月初拥有的钱 ...

  6. 宜信开源|数据库审核软件Themis的规则解析与部署攻略

    一.介绍 Themis是宜信公司DBA团队开发的一款数据库审核产品,可帮助DBA.开发人员快速发现数据库质量问题,提升工作效率.其名称源自希腊神话中的正义与法律女神.项目取此名称,寓意此平台对数据库质 ...

  7. PLSQL_解析过程及硬解析和软解析的区别(案例)

    2014-08-11 Created By BaoXinjian 一.摘要 Oracle硬解析和软解析是我们经常遇到的问题,所以需要考虑何时产生软解析何时产生硬解析,如何判断 1. SQL的执行过程 ...

  8. 共享SQL语句减少硬解析

    这篇文章是参考甲骨论老相老师所做的教学视频: http://v.youku.com/v_show/id_XMzkyMTczMTQ4.html 所做的学习笔记: 接上文: http://nvd11.bl ...

  9. Oracle sql解析类型, 软解析和硬解析浅析

    这篇文章是参考加甲骨论老相老师视频所做的学习笔记: http://www.jiagulun.com/thread-2675-1-1.html Sql 执行的流程分成3部分: 解析部分(Parse): ...

最新文章

  1. 解放程序员双手之Supervisor
  2. 32位oracle和64位的区别,区分你的oracle是64位还是32位
  3. reciprocity
  4. 【Django博客开发教程】:数据查询 Article.objects.all()
  5. MySQL中关于OR条件的优化
  6. Superior Scheduler:带你了解FusionInsight MRS的超级调度器
  7. linux 巡检手册,服务器设备系统巡检标准手册.doc
  8. DataV数据可视化功能特性
  9. 在Extjs中对日期的处理,以及在后端数据在SQL语句的判断处理
  10. Python Scrapy 爬虫框架实例(一)
  11. 【算法模板】链表篇—(附牛客习题)
  12. html5动漫人物小部件制作,虚拟动漫人物制作器app
  13. 90后最流行的英文名
  14. c语言char str什意思,char *str与*str的区别
  15. Win10查看已存储WiFi密码的两种方法
  16. 「水花投资」是什么?是个人吗?
  17. (七)DAC0832 数模转换芯片的应用 以及运算放大器的学习 01
  18. signature=5a537e48de3abe15561f136edabc54dc,Visual Signatures in Video Visualization
  19. CSS3各种手型样式集合
  20. keil cannot reset target shutting 新解决办法

热门文章

  1. 插件怎么用_室内设计,3dmax插件教程,一键生成木地板
  2. 画图解释FHSS、DSSS扩频原理以及计算规则
  3. Pixel修改kernel内核调试
  4. 一起来看流星雨剧情简介/剧情介绍/剧情分集介绍第五集
  5. 传奇GEE引擎版本如何封挂?通过脚本+引擎封玩家账号教程
  6. 圆柱体的投影特点_环形屏幕投影技术的特点和优势
  7. Web前端面试问题集锦
  8. java if打折怎么算_用java写出商品打折程序
  9. 对搜狗搜索引擎的评价
  10. 微信小程序如何从云端获取数据并渲染页面