赞
踩
好久没写了,这次开始重新记录一下问题,我在部署GCN-SLAM代码的时候,源代码用到的是c++的pytorch接口, 所以需用git clone下来pytorch的源码进行cmake构建,在构建过程中改了一下cmakelist中用到库的版本,编译还是失败,原因是找不到我电脑里安装的cuda,解决办法:设置一下CMAKE_CUDA_COMPILER的路径即可
今天来继续解决GCN-SLAM的部署问题,由于自己是3070显卡,所以需要安装支持cuda版本11以上的libtorch,找到了一个汇总版本的网站:https://github.com/pytorch/pytorch/issues/40961,这些都是预编译好的,不需要自己手动编译
由于新版本的需要C++14标准去编译,所以得在cmakelist里添加如下:
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
然后是代码需要改动一下:参考:https://blog.csdn.net/qq_35942419/article/details/120556046?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-120556046-blog-124106912.235%5Ev36%5Epc_relevant_default_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-120556046-blog-124106912.235%5Ev36%5Epc_relevant_default_base3&utm_relevant_index=1
今天下午看了一下李沐老师的深度学习课程,收获颇丰,第一,batch_size的意义就是假设样本一共有n,从中随机选取batch_size个样本放入模型中进行推理,进行参数的更新,这样会减少计算的成本。第二,深度学习中为啥不用牛顿法这种二阶的导数(收敛速度更快)进行最小二乘问题的求解呢,因为大部分模型的统计模型都是错误的,我们对收敛速度快慢并没有要求,收敛太快容易进入次优解,并且一般二阶导数都求不出来
今天重新安装啦一下ubuntu系统,很多东西都存在了网盘里,准备浮现d2net和r2d2特征匹配网络,之前一直下载不下来colmap这次下载一下试了试,有很多错误,参考https://blog.csdn.net/weixin_44172157/article/details/122203759,首先是camke版本太老啦,所以需要用源码安装高版本的,参考https://zhuanlan.zhihu.com/p/519732843,然后cmake …的过程缺什么包就安装什么,其中需要源码安装flann(https://github.com/flann-lib/flann/tree/1.9.1)
其中有个有意思的问题:
并且还会遇到另一个问题:
解决办法很简单:
sudo apt-get install libmetis-dev
结束
在安装d2net的时候需要安装pytorch,由于是用conda安装的,默认的源很慢,所以换啦一下源(https://blog.csdn.net/KIK9973/article/details/118776314)
今天看了一个综述深度学习做特征匹配的视频,感觉可以做,准备跟着他把对应的论文全部看一下,上午的时候跑了一下r2d2net,这个环境是直接和d2net一样的,所以直接用d2net的conda环境即可,听顺利地,因为d2net训练集太大啦,所以看看r2d2net可不可以当作自己的baseline。
今天花了很多时间去搜索深度学习描述子或者特征点提取器替换手工设计的SIFT或者经典特征点或描述子,并且将其应用在SLAM系统里的论文。
之前看的LIFT-SLAM就算一个,它并没对模型进行更改,只是单纯使用KITTI数据集对模型进行了fine tune,然后直接应用在SLAM中,融合的并不是很好。由于在描述子匹配后需要做异常值剔除,异常值阈值设置过高可能会拒绝好的匹配点,导致匹配点过少追踪失败,异常值阈值设置过低会降低三角化的精度。于是文中提出了一种自适应调节异常值拒绝阈值算法,主要思想是保持两帧连续图像的匹配点对保持在一个数值上,通过将地图点从上一帧投影到当前帧来搜索地图点的对应关系。如果匹配点数量降低则降低异常值阈值来提高成功匹配点对来增加地图点数量,如果匹配点数量增大则增大异常值阈值来减少成功匹配点对来减少地图点数量。具体效果如下,可见匹配点数量一直维持在900附近:
作者在实验阶段使用的方法非常不科学,作者将自己提出的LIFT-SLAM系统和DeepVO和NeuralBundler等深度学习算法在仅仅几个数据集序列上进行对比,并且挑选的这几个序列中,DeepVO和NeuralBundler算法原论文作者并没有在这几个序列中做测试,所以没有实验数据,显然LIFT-SLAM效果最好,在DeepVO和NeuralBundler算法测试的序列中,LIFT-SLAM均表现很差。
通过看下来,大部分都是用深度学习替换描述子,使用经典的特征点加上深度学习描述子来做,其中有一个有意思的现象,有人使用HF-NET替换了SLAM的特征提取模块,但是效果并不是很好,于是后面有人做了更牛逼的HF-NET替换SLAM的特征提取模块,并且考虑进去了图片的图像金字塔,提取了不同尺度的特征点,使得系统更加鲁棒。
看完这些论文心里就有底了,可以使用深度学习特征点和描述子算法替换经典SLAM算法的前端,接下来就是去找一个比较不错的算法,跑通之后,想想怎么部署在SLAM系统里。
今天尝试将DX-SLAM跑通,他使用的是HFNET描述子,首先需要配一下HF-NET环境,比较容易,但是有几个小坑,首先TF在2版本以上就没有tf.contrib模块了,所以不能安装2版本以上的,如果硬要用,就需要看看手册自己改了,这里建议安装1.15版本的TF,同时HF-NET给的MAKEFILE里用的是pip3 install去安装的依赖,这样会安装到系统里而不是conda环境里,所以需要自己用pip install去安装。
运行啦一下DX-SLAM在TUM数据集desk1上的效果,刚开始很好,过几秒就跟丢啦
我于是用TUMdesk2的数据集试了一下,不错,在跟踪过程中有关键帧的剔除,不知道是不是和ORB-SLAM2策略一样,感觉不是,最后也发生啦回环
运行命令:
python3 getFeature.py /home/zhang/dataset/TUM/rgbd_dataset_freiburg2_desk/rgb /home/zhang/feature_deep/dxslam-master/feature
这是先提取特征点和描述子,然后运行即可:
./Examples/RGB-D/rgbd_tum Vocabulary/DXSLAM.fbow Examples/RGB-D/TUM2.yaml /home/zhang/dataset/TUM/rgbd_dataset_freiburg2_desk /home/zhang/dataset/TUM/rgbd_dataset_freiburg2_desk/associations.txt /home/zhang/feature_deep/dxslam-master/feature
在跑DX-SLAM空余时间,我去下载啦KITTI数据集,准备试试LIFT-SLAM效果如何,当我按照github说的那样做的时候:
给我报错啦:
于是网去找啦一下源码
发现他在读取参数的时候把特征点和描述子都读进去了,说明需要自己去提LIFT关键点和描述子,但是作者没有给对应的文件,非常不理解,所以就没继续弄了,但是作者提供了一个可以提取LIFT做匹配的demo,匹配用的是暴力匹配,
LIFT:
ORB:
分析:LIFT提那么多点,都没有匹配上,我感觉是匹配算法的问题,换一个匹配算法会不会好?我懒得去验证了。
我又去做了ORB,LIFT,HF-NET对比:
ORB+暴力匹配:
LIFT+暴力匹配:
HF-NET + SUPERGLUE
今天继续在看DXSLAM文章,文章中主要介绍了自己用HF-NET替换了ORB的特征点和描述子,并且为了减少累计误差,结合HF-NET提取的全局特征和BOW设计了一个回环检测框架,同时利用全局特征改进了重定位模块,回环和重定位我应该是做不了,可以在DX-SLAM基础上替换HF-NET,换成别的网络来做这件事。并且论文中提到了很多数据集和一些验证鲁棒性的方法,我准备之后再看,先看看HF-NET如何替换的ORB-SLAM中的特征点和描述子的,自己替换一下试试看
今天下载啦clion可以快乐的看代码啦,今天主要对比一下ORB-SLAM2的代码和DX-SLAM的代码,首先是在主程序rgbtum.cc中,DX-SLAM在这里读取了经过HF-NET处理图片序列得到的特征点和描述子,看源码发现HF-NET输出的特征点只有点的x和y两个坐标值。所以还是需要用传统方法计算一下角度的不太像LIFT,直接有学习角度的模块。(这里是否自己找一个学习角度不错的模块儿替代传统方法呢???),同时DXSLAM只是用HF-NET处理了原图,并没有使用金字塔图层,层层提取,所以这块儿有待改善,通过查看HF-NET输出的特征点文件,很有意思的是一个图片提取啦600多个特征点,程序中做啦判断,最多提取550个,可能是出于计算资源的角度?载入描述子的时候很有意思,他使用的是npy后缀格式的文件,通过搜索发现这个后缀文件的优势有占用空间少,而且读取速度非常非常快,快的离谱,DXSLAM的C++源码是直接256个256个去读取的描述子,他应该在HF-NET的getfeature文件中去调整成ORB读取的格式了,因为ORB使用描述子就是一个特征点有256位的描述子。DXSLAM还读取了全局描述子用于回换和重定位,这俩块儿我还没有看,先把特征点提取的部分替换搞定再去看看吧。
在初始化中,void Tracking::StereoInitialization()函数里,原先ORB-SLAM2要求必须当前帧特征点超过500个才开始,可是DXSLAM只要求200个就可以了,是不是害怕初始化不成功呢?
在恒速模型跟踪中很有意思,DXSLAM创建frame是通过shared_ptr创建的,所以对frame操作的时候需要用->,而ORB-SLAM2是直接用构造函数构造的,所以用.就可以了,这里DXSLAM是不是为了不和ORB-SLAM2重复才刻意这么做的,还是说作者只是单纯的想锻炼一下代码能力呢?
看完这么多,想着能不能构建构建一个图像金字塔,对每个图像都提取特征点和描述子,然后替换原先的ORB-SLAM2里的代码,于是就去研究了一下ORB-SLAM2里的图像金字塔咋搭建的,仿造着搭建啦一下:
一开始输入的灰度图像:
因为需要构建高斯图像金字塔,对图片要进行高斯模糊,所以先进行padding操作,可以看到图像的四周都进行了镜像补边,这次补17个像素,拿这个当作第0层:
然后对这层图像进行缩放,得到第1层图像,可以看到图像的尺寸变小啦,剩下的就是继续padding操作,多少层就这样重复多少次:
但是经过源码查看发现,代码里实际上跑起来的图像金字塔并没有使用padding后的图片,只是单纯进行图像下采样,所以自己构建的时候也需要注意。
今天尝试去看了一下DX-SLAM的match.cc,发现了两个修改的点,第一个就是开头的描述子最大距离:
他这里因为使用的描述子是float类型,所以bestDist需要这样子设计,
可以对比一下ORB-SLAM2中的二进制描述子:
同时因为DX-SLAM使用的是float类型的描述子,所以在计算描述子距离的时候也会有点不同,因为HF-NET使用的是256位的描述子,所以这里i最大是256,这里和二进制描述子不同,它直接进行了描述子的做差取了一范数,这里是否可以换成2范数试试?
这里给出啦ORB-SLAM2原始计算两个二进制描述子汉明距离的代码
目前有几个点不太清楚,首先是如何读取金字塔特征点和描述子,并且赋值给frame的成员变量,如果解决了这个问题,后面就是一些小的问题了,比如说二进制和float可能会冲突。之后再解决吧
今天又来看ORB-SLAM2提取特征点和描述子的部分啦,在一开始使用SYSTEM初始化的时候,创建ORB的提取器,很有意思的地方是提前规定了每一帧提取的特征点总数,这里通过yaml文件传入,ORB-SLAM2规定每帧1000个特征点,这是8层金字塔一共提取1000个点,在后续使用四叉树进行特征点提取(对金字塔每层都使用这样的算法)的时候,会将这1000个点全部分完。
在ORB-SLAM2中同样也计算了每层金字塔应该分多少个点,可以抄这里点代码去分配特征点,在python代码里:
在HF-NET代码里,正好也是规定提取1000个特征点,这样就可ORB-SLAM2里的数目对应上了,但是这样有个弊端,ORB-SLAM2是8层金字塔一共提取1000个点,而HF-NET是单层提取1000个点,显然单层不可能提取那么多,所以这1000个点就是摆设,同时在DX-SLAM的程序中发现他要求最多提取550个特征点,这个数哪来的就不知道了:
注意,ORB-SLAM2利用四叉树对每一层提取了特征点之后,最后将每层金字塔中特征点坐标同一到了第0层,这是需要注意的,这里注意一下ORB-SLAM2提取完成特征点后都有哪些属性,x,和y坐标以及金字塔层数,还有特征点的计算方向的patch,这个数值可以直接计算出来然后赋值:
下面有个很有意思的点,ORB-SLAM2要求提取1000个特征点,所以在双目初始化的时候要求大于500就初始化,而DX-SLAM是提取550个点,所以在初始化的时候要求大于200。
还有就是在恒速模型匹配的时候,利用的是地图点的投影模型,DX-SLAM并没有去做方向一致性检测,即使代码里有这一段,因为DX-SLAM一开始并没有设定特征点的方向,所以均为-1,导致所有特征点方向相同,均通过了方向一致性检测,我认为就是因为DX-SLAM没有使用方向一致性检测,导致对左右摇晃的场景非常不鲁棒,这就是为什么在TUM的1序列的desk的数据集上一摇晃就跟丢!!!!!。
我今天尝试修改DX-SLAM代码,使得他使用图像金字塔进行track,首先修改的就是HF-NET的提取特征点的文件,里面构建啦图像金字塔并且提取了相应的特征点和描述子,然后修改的就是DX-SLAM的rgb-tum.cc主程序里的加载特征点和描述子的函数,使得适配修改后输出的文件,并且在恒速模型中加入了金字塔多层进行特征点匹配。跑起来之后发现方向一致性问题导致左右摇晃跟踪失败问题依然存在,所以下次要解决一下方向一致性检测那块儿。
今天下载了cvlife做的ORB-SLAM2课件,理解了为什么ORB-SLAM2为什么需要计算特征点角度,因为如果图像发生旋转,patten的模式是固定的,它无法跟着旋转,导致同一个特征点在两张图像(旋转后的)中计算得到的描述子不同,所以计算每个特征点的角度,然后先旋转到同一个坐标系中,再提取描述子,这样相对鲁棒,这样是为什么深度学习特征点和描述子为什么用不到灰度质心法算角度,所以在运动一致性检测的地方,也用不了了角度信息计算。所以之前想去做方向一致性检测想法就是错误滴,如何使用别的描述子去做,感觉可以去加入,但是这样会提高这些模型的性能,建议不要这样做。之后要去做什么呢?我建议去接着把ORB-SLAM2的追踪部分再去好好看看,接下来好好理解DX-SLAM在后面都做啦什么,我发现我在DX-SLAM基础上做了图像金字塔,已经把这块儿理解的透透的了
刚刚一直下载不下来evo,这次突然下好啦,所以评估了一下我使用了图像金字塔的DXSLAM在TUM2的desk序列的效果,但是运行evo的命令的时候报错啦:
他的意思是轨迹文件格式不符合tum的格式,不过还好我找到啦解决办法:
cat results.txt | tr -s [:space:] > results_new.txt
改进后的DX-SLAM(加入了图像金字塔),PS:设定一共1000个特征点,导致第0层只分配了200个,效果所以不好啦
ORB-SLAM2的源码效果。。。非常炸裂。。。我再跑一下原版DX-SLAM试一下
不得不说轨迹是真的好看,和grountruth完全一样啦
原版DX-SLAM,但是比ORB-SLAM2弱了将近10倍,可以看到在大概10秒的时候,APE剧增,甚至达到了0.2,偏的离谱:
加入金字塔原理后的DX-SLAM,一共提取3000个点,效果还算可以:
整体轨迹也比较贴合。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。