点击上方“AI算法修炼营”,选择“星标”公众号
精选作品,第一时间送达
论文地址:https://arxiv.org/pdf/1902.11046v3.pdf
代码地址:https://github.com/jiexiong2016/GCNv2_SLAM
出自:英国皇家理工学院本文提出了一种基于深度学习的特征点和描述子提取算法,被命名于GCNv2。GCNv2是基于一个为三维射影几何而训练的网络GCN的改进版本。GCNv2被设计用于生成类似于ORB的特征描述子和特征点的算法,其可以很容易的替代ORB特征在ORB-SLAMv2中。GCNv2可以显著的提升GCN的计算速度,并且不像GCN只能应用于桌面系统。经过本算法改善的ORB-SLAMv2,可以实时运行在嵌入式设备Jetson TX2。实验结果表明,经过重新训练后的GCNv2网络精度和GCN基本相当, 并且提取的特征鲁棒性足以应用于无人机的控制。
上图显示了使用GCN-SLAM进行的无人机定位操作。下图显示了用于分别比较ORB-SLAM2和GCN-SLAM中的特征点检测输出。与ORB(右)相比,GCNv2(左)倾向于预测更多可重复且分布均匀的特征。
简介
定位的能力是大多数移动机器人运行起来的关键。本文专注于解决SLAM系统中的视觉里程计(VO)问题,视觉里程计也是基于视觉的SLAM系统的基础,主要作用是基于视觉信息估计相对运动,具体来说,VO 研究图像帧间变换关系完成实时的位姿跟踪, 对输入的图像进行处理,计算姿态变化, 得到相机间的运动关系。
而特征点的检测和匹配一直是视觉里程计中重要的一个环节,之前的文章中介绍了SIFT、ORB等特征点的检测,都面临着计算量大,耗时长的问题。特征点可以称为兴趣点、显著点、关键点等。以点的位置来表示的点特征是一种最简单的图像特征。 特征点可以分为关键点和描述子两部分。事实上,特征点是一个具有一定特征的局部区域的位置标志,称其为点,是将其抽象为一个位置概念,以便于确定两幅图像中同一个位置点的对应关系,所以在特征匹配过程中是以该特征点为中心,将邻域的局部特征进行匹配。
也就是说在进行特征匹配时首先要为这些特征点建立特征描述,这种特征描述通常称之为描述子。
目前,基于深度学习的特征点检测方法正在不断涌现,代表工作有SuperPoint 、GCN等,而本文提出的GCNv2是基于一个为三维射影几何而训练的网络GCN的改进版本。主要贡献有:
1、与相关的基于深度学习的特征提取方法相比,GCNv2保留了与GCN相当的准确性,显著改进了运动估计的准确性,同时显着减少了推理时间。
2、将特征向量的二值化纳入深度学习网络的训练中,这极大地加快了匹配速度。设计的GCNv2具有与ORB功能相同的描述符格式,并且能够直接用作SLAM系统中的关键点提取器,例如ORB-SLAM2 或SVO2当中。
3、在真正的无人机上使用GCN-SLAM1证明了工作的有效性和鲁棒性,并表明它可以处理ORB-SLAM2特征点丢失等失败的情况。与需要GPU进行实时推理的GCN相比,GCN-SLAM在嵌入式低功耗硬件(例如Jetson TX2)上能够实时运行。
GCN与GCN V2
GCN(出自《Geometric correspondence network for camera motion estimation》)
在GCN中将CNN和RNN结合训练,同时检测关键点并生成其对应的描述子。并借助刚体变换,通过将source frame中的点warp到reference frame中实现对网络的优化。本质上,GCN就是对warp的学习。整个训练过程聚焦于相机的运动而不是图像内部的运动,这会给匹配带来更好的一致性,并且有助于最终的位姿估计。
先是利用CNN提取图像多尺度的特征,然后是浅层的双向循环网络,预测关键点在两张图像的位置。
稠密的特征提取
1、金字塔网络主干:
CNN提取特征分为卷积与反卷两部分:
卷积部分:利用带有bottleneck和batch normalization的ResNet-50。在ImageNet上预训练获得预训练参数。
反卷部分:上采样,恢复图像尺度,并且与卷积部分加入shortcut,从而胡得更加细化的特征。
2、模型的损失函数
以二范数距离作为损失函数,使得网络可以将输入样本按照相似性映射到特征空间,相似的在特征空间距离近,反之则远。带有损失函数的CNN网络训练可以使得特征被优化,从而用于最近邻匹配。
循环mask预测
循环结构:将检测关键特征点作为一个二分类问题,利用CNN提取的稠密特征作为输入。为了同时对两幅图像的关键特征点位置进行预测,网络利用了时间和空间信息。利用浅层双向循环卷积网络来实现该目的。
GCN V2
网络结构
最初的GCN网络是由ResNet-50和双向循环网络实现的。CNN是实现稠密特征提取的,BRNN是在空间信息的基础上加入时间信息的。该结构已经实现了很好的精度,但是无法实时。一方面,该网络结构本身需要大算力的平台支持,而且,双向结构需要同时对两个或多个frame进行匹配,但是KF会基于当前相机位姿进行动态更新,这进一步增加了计算量。
受SuperPoint只对单个帧进行检测的启发,新设计的网络GCN V2对一张原始图像这种的每个cell(大小为16x16像素)进行独立的预测。(这样和ORB-SLAM中的ORB提取一样,可以使得最终提出的特征点均匀分布在图像中)在GNC V2中,所有的池化层都被改为kernel大小为4x4,步长为2,padding为1的卷积层。网络输入的图像尺寸是320x240。
代码为:
class GCNv2(torch.nn.Module):
def __init__(self):
super(GCNv2, self).__init__()
self.elu = torch.nn.ELU(inplace=True)
self.conv1 = torch.nn.Conv2d(1, 32, kernel_size=4, stride=2, padding=1)
self.conv2 = torch.nn.Conv2d(32, 64, kernel_size=4, stride=2, padding=1)
self.conv3_1 = torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
self.conv3_2 = torch.nn.Conv2d(128, 128, kernel_size=4, stride=2, padding=1)
self.conv4_1 = torch.nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1)
self.conv4_2 = torch.nn.Conv2d(256, 256, kernel_size=4, stride=2, padding=1)
# Descriptor
self.convF_1 = torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.convF_2 = torch.nn.Conv2d(256, 256, kernel_size=1, stride=1, padding=0)
# Detector
self.convD_1 = torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.convD_2 = torch.nn.Conv2d(256, 256, kernel_size=1, stride=1, padding=0)
self.pixel_shuffle = torch.nn.PixelShuffle(16)
def forward(self, x):
x = self.elu(self.conv1(x))
x = self.elu(self.conv2(x))
x = self.elu(self.conv3_1(x))
x = self.elu(self.conv3_2(x))
x = self.elu(self.conv4_1(x))
x = self.elu(self.conv4_2(x))
# Descriptor xF
xF = self.elu(self.convF_1(x))
desc = self.convF_2(xF)
dn = torch.norm(desc, p=2, dim=1) # Compute the norm.
desc = desc.div(torch.unsqueeze(dn, 1)) # Divide by norm to normalize.
# Detector xD
xD = self.elu(self.convD_1(x))
det = self.convD_2(xD).sigmoid()
det = self.pixel_shuffle(det)
return desc, det
特征点二进制的描述子
在网络输出的特征向量之后再加上一层,二值响应层。然后设计其误差反向传递的函数。
这种方法比让网络直接输出二进制的描述子训练起来更加高效。如果直接输出二进制的值,即使得输出在{+1,-1}两个值周围聚类,会与之后的基于损失函数的优化会冲突,因为损失函数优化需要用到距离信息来划分相似与否。这样整个网络的训练会不稳定。
特征图 f的大小为256,使得其和ORB特征具有相同的位,方便其整合到基于ORB的视觉跟踪系统中。
GCN V2损失函数
1、triplet loss:用于特征点相似性的区分,使其与真值更近,离负样本更远
其中,正样本的选取是通过ground truth warp到,负样本是通过mining算法得到的。
2、Mask loss:
alpha是超参,用于平衡正负样本(keypoint是正样本,远远少于负样本)
![](https://i-blog.csdnimg.cn/blog_migrate/3969ccaa6cccd8d9f44e954b7d5d42d3.png)
GCN-SLAM
将GCNv2整合到ORB-SLAM2中,组成一个GCN-SLAM系统。
在GCNv2中,向网络输入一个单一的灰度图像帧,该帧输出两个矩阵:一个1×320×240的关键点掩码和一个256×320×240的特征描述符矩阵。对关键字掩码进行阈值处理,以获得一组关键字位置、它们的置信度以及对应的256位特征描述子。对网格大小为8×8的NMS。由于无法知道检测到的特征的方向,将角度设置为零。
最后,完整地保留了ORB-SLAM2的闭环和位姿图优化,除了通过在V-A节中提供的训练数据集中计算bow以适应GCNv2特征描述符之外。
GCN-SLAM在TX2上可以以20Hz运行,在Intel i7-7700HQ和NVIDIA 1070上可以以大约80Hz运行。GCNv2-tiny是较小版本的GCNv2,从第二层开始,feature map的数量被减小了一半。采用GCNv2-tiny的GCN-SLAM可以在TX2上以40Hz运行。(ORB-SLAM中台式机上特征提取大概30多ms,可以达到30fps,构图部分大概380ms—460ms,但是前段和后端独立运行)
实验结果
目的不是测试其优于ORB-SLAM2,而是:
1)更适合高精度的运动估计
2)计算上更高效
3)更鲁邦
A.训练数据
自己做的数据SUN-3D dataset
B.定量结果
采用绝对估计误差(ATE)作为标准,结果如下:
不带闭环:
不带闭环:
C.定性结果
这一结果主要是验证GCNv2的鲁棒性。
GCN比ORB更加稳定,轨迹波动小,而且在ORB丢失的地方GCN实现了很好的跟踪:
其次,GCN提取的kp中inliers占比比ORB多,而且分布更加均匀
最后,就是利用GCN提取的点来重构场景,结果如下:
局限:只是对重投影几何训练,并没有对一般的特征匹配进行训练(这种可以直接利用DL进行场景的匹配来是实现回环重定位),只是对室内进行了测试,并没有进行室外的测试
参考:
https://blog.csdn.net/weixin_42696356/article/details/90744594
SLAM系列视觉SLAM前端:视觉里程计和回环检测视觉SLAM后端:后端优化和建图模块视觉SLAM中特征点法开源算法:PTAM、ORB-SLAM视觉SLAM中直接法开源算法:LSD-SLAM、DSO视觉SLAM中特征点法和直接法的结合:SVO
2020年最新的iPad Pro上的激光雷达是什么?来聊聊激光SLAM