目录
35、ORB SLAM里面的Local Map和VINS-Mono里面的滑窗法有什么区别?
38、BA中,相机位姿很快接近真值,但地图点却不能很快的收敛,这是为什么?
43、BA中Hessian矩阵求逆除了边缘化和gpu还有哪些加速的办法?
44. PnP求解只有一个点对时的自由度?两个点对时的自由度?
48、对于动态光线明暗变化、动态场景,视觉SLAM如何去解决?
比较难的面试题目汇总如下:
https://www.freesion.com/article/35571024388/#6.%20%E4%BB%8B%E7%BB%8D%E4%B8%8BVO
29、3D地图点是怎么存储的?表达方式?
以ORB SLAM2为例,3D地图点是以类的形式存储的,在类里面除了
- 存储3D地图点的空间坐标;
- 同时还存储了3D点对应的(多个)图像点的描述子(其实就是BRIEF描述子),用来快速进行与特征点的匹配;
- 同时还用一个map存储了与其有观测关系的关键帧以及其在关键帧中的Index等等。
class MapPoint
{
// ...
protected:
// Position in absolute coordinates
cv::Mat mWorldPos;
// Keyframes observing the point and associated index in keyframe
std::map<KeyFrame*,std::tuple<int,int> > mObservations;
// For save relation without pointer, this is necessary for save/load function
std::map<long unsigned int, int> mBackupObservationsId1;
std::map<long unsigned int, int> mBackupObservationsId2;
// Mean viewing direction
cv::Mat mNormalVector;
// Best descriptor to fast matching
cv::Mat mDescriptor;
// Reference KeyFrame
KeyFrame* mpRefKF;
long unsigned int mBackupRefKFId;
// Tracking counters
int mnVisible;
int mnFound;
// Bad flag (we do not currently erase MapPoint from memory)
bool mbBad;
MapPoint* mpReplaced;
// For save relation without pointer, this is necessary for save/load function
long long int mBackupReplacedId;
// Scale invariance distances
float mfMinDistance;
float mfMaxDistance;
Map* mpMap;
std::mutex mMutexPos;
std::mutex mMutexFeatures;
std::mutex mMutexMap;
};
30、地图点的构建方法有哪些?
(1)ORB SLAM2中是根据三角化的方法确定地图点的,利用匹配好的两个点构建AX=b的方程,然后利用SVD分解去最小奇异值对应的特征向量作为地图点坐标。,参考多视图几何总结——三角形法。
(2)在SVO中是利用深度滤波器进行种子点深度更新,当种子点深度收敛后就加入了地图构建地图点。
31、RGB-D的SLAM和RGB的SLAM有什么区别?
32、边缘检测算子汇总
边缘检测一般分为三步,分别是滤波、增强、检测。基本原理都是用高斯滤波器进行去噪,之后在用卷积内核寻找像素梯度。常用有三种算法:canny算子,sobel算子,laplacian算子。
canny算子:一种完善的边缘检测算法,抗噪能力强,用高斯滤波平滑图像,用一阶偏导的有限差分计算梯度的幅值和方向,对梯度幅值进行非极大值抑制,采用双阈值检测和连接边缘。
sobel算子:一阶导数算子,引入局部平均运算,对噪声具有平滑作用,抗噪声能力强,计算量较大,但定位精度不高,得到的边缘比较粗,适用于精度要求不高的场合。
laplacian算子:二阶微分算子,具有旋转不变性,容易受噪声影响,不能检测边缘的方向,一般不直接用于检测边缘,而是判断明暗变化。
(1) Canny算子
Canny边缘检测算法可以分为以下5个步骤:
(1)使用高斯滤波器,以平滑图像,滤除噪声。
(2)计算图像中每个像素点的梯度强度和方向。
(3)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
(4)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
(5)通过抑制孤立的弱边缘最终完成边缘检测。
这里值得细究的非极大值抑制算法和双阈值滤波算法,如下:
要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。图中中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点。如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。这就是非极大值抑制的工作原理。
左侧是没有经过非极大值抑制的梯度,右侧是经过非极大值抑制后的梯度, 完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128。
Canny算法中减少假边缘数量的方法是采用双阈值滤波算法,选择两个阈值,根据高阈值得到一个边缘图像,这样一个图像含有很少的假边缘,但是由于阈值较高,产生的图像边缘可能不闭合,未解决这样一个问题采用了另外一个低阈值。在高阈值图像中把边缘链接成轮廓,当到达轮廓的端点时,该算法会在断点的8邻域点中寻找满足低阈值的点,再根据此点收集新的边缘,直到整个图像边缘闭合。
如上图所示,E1为低阈值滤波的结果,E2为高阈值滤波的结果。
以下几种边缘检测算子相比之下就简单很多,更像一个卷积核操作