IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【记录读论文时遇到的一些算法2】—— Occupancy Grid Map -> 正文阅读

[人工智能]【记录读论文时遇到的一些算法2】—— Occupancy Grid Map

1.机器人地图的分类

地图有很多种表示方式,例如,用经纬度标识地方的世界地图,城市的地铁图,校园指引图。

第一种我们称为尺度地图(Metric Map),每一个地点都可以用坐标来表示,比如北京在东经116°23′17’‘,北纬39°54′27’';第二种我们称为拓扑地图(Topological Map),每一个地点用一个来表示,用来连接相邻的点,即图论中的(Graph),比如从地铁路线图中我们知道地铁红磡站与旺角东站和尖东站相连;第三种我们称为语义地图(Semantic Map),其中每一个地点和道路都会用标签的集合来表示,例如,有人问我中山大学教学楼E栋在哪里,我会说在图书馆正门右手边靠近图书馆的一侧。

在机器人领域,尺度地图常用于定位于地图构建(Mapping)、定位(Localization)和同时定位与地图构建(Simultaneous Localization And Mapping,SLAM),拓扑地图常用于路径规划(Path Planning),而语义地图常用于人机交互(Human Robot Interaction)。

这节课我们将介绍如何用机器人传感器数据绘制尺度地图。这有什么难点呢?首先也是最重要的一点,传感器数据有噪音。用激光传感器检测前方障碍物距离机器人多远,不可能检测到一个准确的数值。如果准确值是 2 \sqrt 2 2 ? 米,有时会测出1.42米,有时甚至1.35米。另外,传感器数据是本地坐标系的,而机器人要构建的是一个全局的地图。最后,机器人会运动,运动也是有噪音的。总结起来就两个字,噪音。通俗点来讲,“不准”。

2.占据栅格地图

我们首先来介绍机器人Mapping用到的的传感器,它叫做激光传感器(Laser Sensor),如下图所示:

在这里插入图片描述
激光传感器会向固定的方向发射激光束,发射出的激光遇到障碍物会被反射,这样就能得到激光从发射到收到的时间差,乘以速度除以二就得到了传感器到该方向上最近障碍物的距离。
这样看来,似乎利用激光传感器,机器人能够很好地完成Mapping这一任务。但是我们前面提到了,传感器数据是有噪音的。例如,假如我们在此时检测到距离障碍物4米,下一时刻检测到距离障碍物4.1米,我们是不是应该把4米和4.1米的地方都标记为障碍物?又或者怎么办呢?

为了解决这一问题,我们引入占据栅格地图(Occupancy Grid Map)的概念。

我们首先来解释这里的占据率 (Occupancy) 指的是什么。在通常的尺度地图中,对于一个点, 它要么有 (Occupied状态,下面用1来表示) 障碍物,要么没有 (Free状态,下面用0来表示) 障碍物 (旁白:那么问题来了,薛定谔状态呢? )。在占据栅格地图中,对于一个点,我们用 p ( s = 1 ) p(s=1) p(s=1) 来表示它是Free状态的概率,用 p ( s = 0 ) p(s=0) p(s=0) 来表示它是Occupied状态的概率,当然两者的和为 1 。两个值太多了,我们引入两者的比值来作为点的状态: Odd ? ( s ) = p ( s = 1 ) p ( s = 0 ) \operatorname{Odd}(s)=\frac{p(s=1)}{p(s=0)} Odd(s)=p(s=0)p(s=1)?
对于一个点,新来了一个测量值 (Measurement, z ~ { 0 , 1 } z \sim\{0,1\} z{0,1} ) 之后我们需要更新它的状态。 假设测量值来之前,该点的状态为 Odd ? ( s ) \operatorname{Odd}(s) Odd(s) ,我们要更新它为: Odd ? ( s ∣ z ) = p ( s = 1 ∣ z ) p ( s = 0 ∣ z ) \operatorname{Odd}(s \mid z)=\frac{p(s=1 \mid z)}{p(s=0 \mid z)} Odd(sz)=p(s=0z)p(s=1z)? 。 这种表达方式类似于条件概率,表示在 z z z 发生的条件下 s s s 的状态。
根据贝叶斯公式,我们有:
p ( s = 1 ∣ z ) = p ( z ∣ s = 1 ) p ( s = 1 ) p ( z ) p ( s = 0 ∣ z ) = p ( z ∣ s = 0 ) p ( s = 0 ) p ( z ) \begin{aligned} &p(s=1 \mid z)=\frac{p(z \mid s=1) p(s=1)}{p(z)} \\ &p(s=0 \mid z)=\frac{p(z \mid s=0) p(s=0)}{p(z)} \end{aligned} ?p(s=1z)=p(z)p(zs=1)p(s=1)?p(s=0z)=p(z)p(zs=0)p(s=0)??
带入之后,我们得
O d d ( s ∣ z ) = p ( s = 1 ∣ z ) p ( s = 0 ∣ z ) = p ( z ∣ s = 1 ) p ( s = 1 ) / p ( z ) p ( z ∣ s = 0 ) p ( s = 0 ) / p ( z ) = p ( z ∣ s = 1 ) p ( z ∣ s = 0 ) O d d ( s ) \begin{aligned} O d d(s \mid z) &=\frac{p(s=1 \mid z)}{p(s=0 \mid z)} \\ &=\frac{p(z \mid s=1) p(s=1) / p(z)}{p(z \mid s=0) p(s=0) / p(z)} \\ &=\frac{p(z \mid s=1)}{p(z \mid s=0)} O d d(s) \end{aligned} Odd(sz)?=p(s=0z)p(s=1z)?=p(zs=0)p(s=0)/p(z)p(zs=1)p(s=1)/p(z)?=p(zs=0)p(zs=1)?Odd(s)?

我们对两边取对数得:
log ? O d d ( s ∣ z ) = log ? p ( z ∣ s = 1 ) p ( z ∣ s = 0 ) + log ? O d d ( s ) \log O d d(s \mid z)=\log \frac{p(z \mid s=1)}{p(z \mid s=0)}+\log O d d(s) logOdd(sz)=logp(zs=0)p(zs=1)?+logOdd(s)
这样,含有测量值的项就只剩下了 log ? p ( z ∣ s = 1 ) p ( z ∣ s = 0 ) \log \frac{p(z \mid s=1)}{p(z \mid s=0)} logp(zs=0)p(zs=1)? 。我们称这个比值为测量值的模型(Measurement Model),标记为 lomeas 。测量值的模型只有两种:
l o f r e e = log ? p ( z = 0 ∣ s = 1 ) p ( z = 0 ∣ s = 0 ) lo_{free} =\log \frac{p(z=0 \mid s=1)}{p(z=0 \mid s=0)} lofree?=logp(z=0s=0)p(z=0s=1)? l o o c c u = log ? p ( z = 1 ∣ s = 1 ) p ( z = 1 ∣ s = 0 ) lo_{occu} =\log \frac{p(z=1 \mid s=1)}{p(z=1 \mid s=0)} looccu?=logp(z=1s=0)p(z=1s=1)? ,而且都是定值。
这样,如果我们用 log ? O d d ( s ) \log O d d(s) logOdd(s) 来表示位置 s s s 的状态 S S S 的话,我们的更新规则就进一步简化成 了: S + = S ? + l o m e a s S^{+}=S^{-}+lomeas S+=S?+lomeas。其中 S + S^{+} S+ S ? S^{-} S?分别表示测量值之后和之前 s s s 的状态。
另外,在没有任何测量值的初始状态下,一个点的初始状态
S i n i t = log ? O d d ( s ) = log ? p ( s = 1 ) p ( s = 0 ) = log ? 0.5 0.5 = 0 ?。? S_{i n i t}=\log O d d(s)=\log \frac{p(s=1)}{p(s=0)}=\log \frac{0.5}{0.5}=0 \text { 。 } Sinit?=logOdd(s)=logp(s=0)p(s=1)?=log0.50.5?=0??
经过这样的建模,更新一个点的状态就只需要做简单的加减法了。这,就是数学的魅力。
例如,假设我们设定 l o o c c u = 0.9 lo_{occu}=0.9 looccu?=0.9 l o f r e e = ? 0.7 lo_{free}=-0.7 lofree?=?0.7 。那么,一个点状态的数值越大,就表 示越肯定它是Occupied状态,相反数值越小,就表示越肯定它是Free状态。

在这里插入图片描述
上图就展示了用两个激光传感器的数据更新地图的过程。在结果中,一个点颜色越深表示越肯定它是Free的,颜色越浅表示越肯定它是Occupied的。

3.TSDF(Truncated Signed Distance Function)

TSDF(Truncated Signed Distance Function)是实时3D重建经典算法,简单可并行,极大推动了实时三维重建的发展。TSDF是SDF的改进,讲取值限制在[-1,1]之间,同时仅在物体表面的限定的距离范围内进行计算,降低了计算量。

TSDF思路很朴素,用一个大的空间包围盒(volume)去包括进去待3D构建的场景,volume成多个voxel(小立体方块):

在这里插入图片描述

如何计算tsdf?假设已经从深度相机获得多帧RGBD图像以及相机的位姿T。

在这里插入图片描述
左图中灰色小方格表示体素voxel,蓝色三角性表示视场,绿色线为截面对应的线。
第一步:计算体素 x x x 在世界坐标系下的坐标。记体素 x x x 在TSDF地图上得坐标为 ( v x , v y , v z ) \left(v_{x}, v_{y}, v_{z}\right) (vx?,vy?,vz?) -则该体素在世界坐标系下的位置为:
P x , ?world? = ( x 0 + v x ? ?Voxel.? x , y 0 + v y ? ?Voxel.? y , z 0 + v z ? ?Voxel.? z ) P_{x, \text { world }}=\left(x_{0}+v_{x} \cdot \text { Voxel. } x, y_{0}+v_{y} \cdot \text { Voxel. } y, z_{0}+v_{z} \cdot \text { Voxel. } z\right) Px,?world??=(x0?+vx???Voxel.?x,y0?+vy???Voxel.?y,z0?+vz???Voxel.?z)
第二步:计算体素在相机坐标系下的坐标。相机的旋转为 R R R 平移为 T T T ,则 P x , c a m e r a = R P x , w o r l d + T P_{x, c a m e r a}=R P_{x, w o r l d}+T Px,camera?=RPx,world?+T
第三步:根据相机内参 K K K 计算体素在相机坐标系下 z z z 向深度 cam ? z ( x ) \operatorname{cam}_{z}(x) camz?(x) :
第四步:重投影计算沿光心经过体素 x x x 到达物体表面 p p p 点对应的 z z z 向深度:因为RGBD的信息 已经知道,所以根据 P x , c a m e r a P_{x, c a m e r a} Px,camera? 可以直接查到 p p p 的深度值 depth ? ( pic ? ( x ) ) \operatorname{depth}(\operatorname{pic}(x)) depth(pic(x))
第五步:得到sdf: s d f i ( x ) = depth ? i ( p i c ( x ) ) ? cam ? z ( x ) s d f_{i}(x)=\operatorname{depth}_{i}(p i c(x))-\operatorname{cam}_{z}(x) sdfi?(x)=depthi?(pic(x))?camz?(x)
第六步:截断: t s d f i ( x ) = max ? ( ? 1 , min ? ( 1 , s d f i ( x ) t ) ) t s d f_{i}(x)=\max \left(-1, \min \left(1, \frac{s d f_{i}(x)}{t}\right)\right) tsdfi?(x)=max(?1,min(1,tsdfi?(x)?)) 即将sdf截断在 [ ? t , t ] [-\mathrm{t}, \mathrm{t}] [?t,t] 内,sdf超 过这个范围的voxel点不用计算,直接得1或者-1。

在这里插入图片描述

第七步:将当前帧得到的值合并到已有的volume。通过将多帧合并成一个TSDF,既可以提升精度 又可以补全单帧缺失的信息。
TSDFi ? ( x ) = W i ? 1 ( x ) T S D F i ? 1 ( x ) + w i ( x ) t s d f i ( x ) W i ? 1 ( x ) + w i ( x ) W i ( x ) = W i ? 1 ( x ) + w i ( x ) \begin{aligned} &\operatorname{TSDFi}(x)=\frac{W_{i-1}(x) T S D F_{i-1}(x)+w_{i}(x) t s d f_{i}(x)}{W_{i-1}(x)+w_{i}(x)} \\ &W_{i}(x)=W_{i-1}(x)+w_{i}(x) \end{aligned} ?TSDFi(x)=Wi?1?(x)+wi?(x)Wi?1?(x)TSDFi?1?(x)+wi?(x)tsdfi?(x)?Wi?(x)=Wi?1?(x)+wi?(x)?
对于需要更新的voxel w i ( x ) = 1 w_{i}(x)=1 wi?(x)=1 ,没在当前视场内的点为 0 。
最后: 重复遍历所有帧,得到合并后的TSDF。

参考文章

[1] https://zhuanlan.zhihu.com/p/21738718 占据栅格地图(Occupancy Grid Map)
[2] https://zhuanlan.zhihu.com/p/487277749 TSDF地图算法分析 实时三维重建

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:41:49  更:2022-04-26 11:44:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:02:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码