(1)确定匹配最大距离,汉明距离小于最小距离的两倍
(2)使用KNN-matching算法,令K=2。则每个match得到两个最接近的descriptor,然后计算最接近距离和次接近距离之间的比值,当比值大于既定值时,才作为最终match。
(3)RANSAC(使用RANSAC找到最佳单应性矩阵。由于这个函数使用的特征点同时包含正确和错误匹配点,因此计算的单应性矩阵依赖于二次投影的准确性)
(4)交叉匹配。针对暴力匹配,可以使用交叉匹配的方法来过滤错误的匹配。交叉过滤的思想很简单,再进行一次匹配,反过来使用被匹配到的点进行匹配,如果匹配到的仍然是第一次匹配的点的话,就认为这是一个正确的匹配。举例来说就是,假如第一次特征点A使用暴力匹配的方法,匹配到的特征点是特征点B;反过来,使用特征点B进行匹配,如果匹配到的仍然是特征点A,则就认为这是一个正确的匹配,否则就是一个错误的匹配。OpenCV中BFMatcher已经封装了该方法,创建BFMatcher的实例时,第二个参数传入true即可,BFMatcher bfMatcher(NORM_HAMMING,true)。
参考链接
BA的本质是一个优化模型,其目的是最小化重投影/光度误差,用于优化相机位姿和世界点。局部BA用于优化局部的相机位姿,提高跟踪的精确度;全局BA用于全局过程中的相机位姿,使相机经过长时间、长距离的移动之后,相机位姿还比较准确。BA是一个图优化模型,一般选择LM(Levenberg-Marquardt)算法并在此基础上利用BA模型的稀疏性进行计算;可以直接计算,也可以使用g2o或者Ceres等优化库进行计算。
Bundle Adjustment : 从视觉重建中提炼出最优的3D模型和相机参数(内参和外参),好似每一个特征点都会反射几束光线,当把相机位姿和特征点位置做出最优的调整后,这些光线都收束到相机相机光心。也就是根据相机的投影模型构造构造代价函数,利用非线性优化(比如高斯牛顿或列文伯格马夸而尔特)来求最优解,利用雅克比矩阵的稀疏性解增量方程,得到相机位姿和特征点3D位置的最优解。
BA可以分为基于滤波器的BA和基于迭代的BA
(1) GN:线搜索
将 f ( x ) f(x) f(x)进行一节泰勒展开,最后求解
线性方程 H △ x = b H△x=b H△x=b;
用 J T ∗ J J^T*J JT∗J近似 H H H矩阵,省略 H H H复杂的计算过程;
稳定性差,可能不收敛;
(2) LM:信赖区域;
求解线性方程 ( H + λ I ) △ x = b (H+λI)△x=b (H+λI)△x=b;
提供更稳定,更准确的增量
(3)
当λ= 0时,L-M等于G-N;
当λ= ∞时,L-M等于一阶梯度下降
旋转矩阵自身是带有约束的,正交且行列式为1,他们作为优化变量时,会引入额外的约束,时优化变的困难,通过李群李代数的转换关系,把位姿估计变成无约束的优化问题。
所谓极线约束就是说同一个点在两幅图像上的映射,已知左图映射点p1,那么右图映射点p2一定在相对于p1的极线上,这样可以减少待匹配的点数量。(画图解释)
绑架问题就是重定位,是指机器人在缺少之前位置信息的情况下,如何去确定当前位姿。例如当机器人被安置在一个已经构建好地图的环境中,但是并不知道它在地图中的相对位置,或者在移动过程中,由于传感器的暂时性功能故障或相机的快速移动,都导致机器人先前的位置信息的丢失,在这种情况下如何重新确定自己的位置。
特征点法
优点:
(1)精确,直接法属于强假设
(2)运动过大时,只要匹配点在像素内,则不太会引起误匹配,鲁棒性好
缺点:
(1)关键点提取、描述子、匹配耗时长
(2)特征点丢失场景无法使用
(3)只能构建稀疏地图
直接法
优点:
(1)省去计算特征点、描述子时间
(2)可以用在特征缺失的场合(比如白墙)
(3)可以构建半稠密乃至稠密地图
缺点:
(1)易受光照和模糊影响
(2)运动必须微小,要求相机运动较慢或采样频率较高(可以用图像金字塔改善)
(3)非凸性;单个像素没有区分度
(1) 误差函数不同。特征点法是重投影误差,直接法是光度误差
(2) 雅克比矩阵不同
我的答案:匹配方法不同。
直接法是通过最小光度误差来匹配特征点,而光流法是通过计算
光流仅估计了像素间的平移,但像素梯度以及灰度关于时间的导数来预测像素在下一时刻的位置。
其他人答案:
(1)没有用相机结构
(2)没有考虑相机的旋转和图像缩放
(3)边界点追踪效果差
(1) EKF假设了马尔科夫性,认为k时刻的状态只与k-1时刻有关。非线性优化使用所有的历史数据,做全体的SLAM
(2) EKF做了线性化处理,在工作点处用一阶泰勒展开式近似整个函数,但在工作点较远处不一定成立。非线性优化每迭代一次,状态估计发生改变,我们会重新对新的估计点做 泰勒展开
可以把EKF看做只有一次迭代的BA
单目:成本低,搭建简单,单目相机有尺度不确定性,需要专门初始化
双目:不需要专门初始化,能够计算深度,基线距离越大,测量距离越远,可以用于室内和室外,标定较为复杂,视差计算比较消耗资源
深度:测量范围窄,噪声大,易受日光干扰,无法测量透射材料,主要用于室内
边缘检测一般分为三步,分别是滤波、增强、检测。基本原理都是用高斯滤波器进行去噪,之后在用卷积内核寻找像素梯度。常用有三种算法:canny算子,sobel算子,laplacian算子
canny算子:一种完善的边缘检测算法,抗噪能力强,用高斯滤波平滑图像,用一阶偏导的有限差分计算梯度的幅值和方向,对梯度幅值进行非极大值抑制,采用双阈值检测和连接边缘。
sobel算子:一阶导数算子,引入局部平均运算,对噪声具有平滑作用,抗噪声能力强,计算量较大,但定位精度不高,得到的边缘比较粗,适用于精度要求不高的场合。
laplacian算子:二阶微分算子,具有旋转不变性,容易受噪声影响,不能检测边缘的方向,一般不直接用于检测边缘,而是判断明暗变化。
G-N中的H矩阵可能为奇异矩阵或者病态矩阵,导致算法不收敛。而且当步长较大时,也无法保证收敛性,所以采用L-M求解增量方程,但是它的收敛速度可能较慢。
RANSAC算法的基本假设是样本中包含正确数据(inliers,可以被模型描述的数据),也包含异常数据(outliers,偏离正常范围很远、无法适应数学模型的数据),即数据集中含有噪声。这些异常数据可能是由于错误的测量、错误的假设、错误的计算等产生的。同时RANSAC也假设,给定一组正确的数据,存在可以计算出符合这些数据的模型参数的方法。
优缺点:
RANSAC算法的优点是能鲁棒的估计模型参数。例如,他能从包含大量局外点的数据集中估计出高精度的参数。缺点是它计算参数的迭代次数没有上限,如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。RANSAC只有一定的概率得到的可信的模型,概率与迭代次数成正比。另一个缺点是它要求设置跟问题相关的阈值,RANSAC只能从特定的数据集中估计出一个模型,如果存在两个(或多个)模型,RANSAC不能找到别的模型。
算法流程:
《视觉slam十四讲》P164
①选择节点和边,确定参数化形式
②加入节点和边
③选择初值,开始迭代
④计算J和H
⑤解H△x = -b
⑥GN/LM
g2o需要实现其中的③-⑥
①选择线性方程求解器(PCG/Cspare/Choldmod)
②选择一个blockslover
③选择迭代方式(GN/LM/Dogleg)
节点:g2o :: VertexSE3Expmap(相机位姿)
g2o :: VertexSBApointXYZ(路标)
边:g2o :: EdgeProjectXYZ2UV(重投影误差)
雅克比矩阵维度:误差项数误差变量数
2000360
信息矩阵维度:误差变量数误差变量数
360360
预测:如何从上一时刻的状态,根据输入信息推断当前时刻的状态分布(先验)
计算协方差
更新:计算增益Kg,然后计算后验
相机内参包括焦距fx,fy,cx,cy,径向畸变系数k1,k2,k3,切向畸变系数p1,p2
其中内参一般来说是不会改变,但是当使用可变焦距镜头时每次改变焦距需要重新标定内参
当图像裁剪时内参cx,cy会发生改变,比如图像从88变成44时,cx,cy需要除以2
一般标定工业相机时只需要得到畸变系数k1,k2即可,对于畸变系数较大的鱼眼相机需要得到k3,p1,p2
相机外参分为旋转矩阵R和平移矩阵t,旋转矩阵和平移矩阵共同描述了如何把点从世界坐标系
转换到摄像机坐标系
世界坐标系(world) 相机坐标(camera) 像素坐标(pixel)
world —— camera: P C = T c w ∗ P w P_{C}=T_{cw} * P_w PC=Tcw∗Pw
camera —— world: P w = T c w − 1 ∗ P c P_w=T_{cw}^{-1} * P_c Pw=Tcw−1∗Pc
pixel —— camera: u = f x ∗ X c / Z c + C x ; v = f y ∗ Y c / Z c + C y u=f_x * X_c / Z_c+C_x ; \quad v=f_y * Y_c / Z_c+C_y u=fx∗Xc/Zc+Cx;v=fy∗Yc/Zc+Cy
camera —— pixel: X c = ( u − C x ) ∗ Z c / f x ; Y c = ( v − C y ) ∗ Z c / f y ; Z c = d X_{c}=(u-C_x) * Z_c / f_x ; \quad Y c=(v-C y) * Z_c / f_y ; \quad Z_c=d Xc=(u−Cx)∗Zc/fx;Yc=(v−Cy)∗Zc/fy;Zc=d
工程目录下有GPS保存的坐标文件gps.txt和激光雷达保存的坐标文件laser.txt两个文件,两个文件的第一列为记录当前数据的时间戳,后两列为坐标。由于GPS每隔500时间单位保存一次数据,激光雷达每隔300时间单位保存一次数据,因此,一段时间内激光雷达保存的数据比GPS保存的数据要多。现在想取出两个文件中时间戳最接近的数据,并分别存放在gps2.txt和laser2.txt中,编写程序实现。(不知道哪位大神能讲下这道题。。。)