欢迎访问我的博客首页。
1. 关键帧
??阅读 ORB_SLAM 的源码最好从 KeyFrame.cc 开始。因为 KeyFrame.cc 中定义了一些很重要的数据结构,比如共视图、生成树。同时,KeyFrame.cc 中的函数几乎不会调用其它文件中的函数,而里程计、回环检测、回环闭合、优化等经常调用 KeyFrame.cc 中的函数,所以 KeyFrame.cc 即简单又重要。
1.1 相机坐标系原点在世界坐标系中的坐标
??已知相机坐标到世界坐标的变换是
R
w
c
R_{wc}
Rwc? 和
t
w
c
t_{wc}
twc?,求相机坐标系原点
O
c
O_c
Oc? 在世界坐标系中的坐标
O
c
w
O_c^w
Ocw?:假设相机坐标系原点
O
c
O_c
Oc? 在相机坐标系中的坐标是
O
c
c
O_c^c
Occ?,由
R
w
c
O
c
c
+
t
w
c
=
O
c
w
R_{wc} O_c^c + t_{wc} = O_c^w
Rwc?Occ?+twc?=Ocw? 知
O
c
w
=
t
w
c
.
(1.1)
O_c^w = t_{wc}. \tag{1.1}
Ocw?=twc?.(1.1)
??已知世界坐标到相机坐标的变换是
R
c
w
R_{cw}
Rcw? 和
t
c
w
t_{cw}
tcw?,求相机坐标系原点
O
c
O_c
Oc? 在世界坐标系中的坐标
O
c
w
O_c^w
Ocw?:假设相机坐标系原点
O
c
O_c
Oc? 在世界坐标系中的坐标是
O
c
w
O_c^w
Ocw?,由
R
c
w
O
c
w
+
t
c
w
=
O
c
c
R_{cw} O_c^w + t_{cw} = O_c^c
Rcw?Ocw?+tcw?=Occ? 知
O
c
w
=
?
R
w
c
t
c
w
.
(1.2)
O_c^w = - R_{wc} t_{cw}. \tag{1.2}
Ocw?=?Rwc?tcw?.(1.2)
??上面两个公式的推导中,很明显
O
c
c
=
0
O_c^c = \bf 0
Occ?=0。由公式 (1.1) 和公式 (1.2) 还可以知道
t
w
c
=
?
R
w
c
t
c
w
t_{wc} = - R_{wc} t_{cw}
twc?=?Rwc?tcw?。
1.2 共视图
??有共同地图点的两个关键帧相连,组成共视图。共视图的创建过程:
void KeyFrame::UpdateConnections();
void KeyFrame::AddConnection(KeyFrame *pKF, const int &weight);
void KeyFrame::UpdateBestCovisibles();
图 1 ORB_SLAM 中的树与图
??有共同地图点的两个关键帧只称为有连接关系,共同地图点数大于等于 15 的两个关键词才有共视关系:
set<KeyFrame *> KeyFrame::GetConnectedKeyFrames() {
unique_lock<mutex> lock(mMutexConnections);
set<KeyFrame *> s;
for (map<KeyFrame *, int>::iterator mit = mConnectedKeyFrameWeights.begin(); mit != mConnectedKeyFrameWeights.end(); mit++)
s.insert(mit->first);
return s;
}
vector<KeyFrame *> KeyFrame::GetVectorCovisibleKeyFrames() {
unique_lock<mutex> lock(mMutexConnections);
return mvpOrderedConnectedKeyFrames;
}
1.3 生成树
??一个连通无向图 G 的生成树 T 是 G 的一个极小连通子图,T 含有 G 中的全部 n 个顶点,但只有足以构成一棵树的 n - 1 条边。
??与该关键帧的共同地图点数量最多的关键帧,被选为该关键帧的父结点。生成树的权重就是共同地图点的数量。生成树的创建过程:
void KeyFrame::UpdateConnections() {
if (mbFirstConnection && mnId != 0) {
mpParent = mvpOrderedConnectedKeyFrames.front();
mpParent->AddChild(this);
mbFirstConnection = false;
}
}
1.4 本质图
|