KeyFrame类

关键帧类主要是进行Covisbility Graph, Essential,Spanning Tree 三个图的维护,更新。
其中不涉及关键帧的筛选策略问题,只设置了剔除某关键帧和剔除关键帧后如何更新图的方法。总体来说,不难理解。
PS:本文设计多线程编程加锁问题 mutex
部分函数笔记:

KeyFrame::KeyFrame(Frame &F, Map *pMap, KeyFrameDatabase *pKFDB)

构造函数:列表初始化 ,将每个关键帧分成若干个网格,设置关键帧位姿信息。

void KeyFrame::SetPose(const cv::Mat &Tcw_)

由Tcw求出R,t,Twc,本来Twc=Tcw的逆,为了避免求逆使用了一些技巧。
在这里插入图片描述

void KeyFrame::UpdateConnections()

更新图的连接,这也是keyframe类主要要干的事。
步骤一:遍历当前帧所能观测到的所有地图点。
步骤二:针对每个地图点找出能观测到它的关键帧,并统计每个关键帧能观察到当前关键帧地图点的个数
步骤三:找出共视数量大于15的关键帧,把他们和当前帧连接。如果没有大于阈值的连接数,则将和关键帧观察到相同的地图点最多的关键帧和当前关键帧进行链接。
步骤四:把所有共视关键帧按权重进行排序,放入容器。
步骤五:如果当前帧是第一次加入到图中来,当前关键帧是第一次和别的关键帧进行连接,找出共识关键帧集合里与当前关键帧共识最多的那个关键帧,作为当前关键帧的父关键帧,他是子关键帧。
在这里插入图片描述

void KeyFrame::SetBadFlag()

设置坏帧标志位:
步骤一:遍历所有和当前关键帧共视的关键帧,删除他们与当前关键帧的联系。
步骤二:遍历每一个当前关键帧的地图点,删除每一个地图点和当前关键帧的联系。
步骤三:清空和当前关键帧的共视关键帧集合和带顺序的关键帧集合。
步骤四:共视图更新完毕后,还需要更新生成树。这个比较难理解。。。真实删除当前关键帧之前,需要处理好父亲和儿子关键帧关系,不然会造成整个关键帧维护的图断裂,或者混乱,不能够为后端提供较好的初值。
理解起来就是父亲挂了,儿子需要找新的父亲,在候选父亲里找,当前帧的父亲(mpParent)肯定在候选父亲中
步骤五:遍历所有把当前关键帧当成父关键帧的子关键帧。重新为他们找父关键帧。设置一个候选父关键帧集合(集合里包含了当前帧的父帧和子帧?)
步骤六:对于每一个子关键帧,找到与它共视的关键帧集合,遍历它,看看是否有候选父帧集合里的帧,如果有,就把这个帧当做新的父帧。
步骤七:如果有子关键帧没有找到新的父帧,那么直接把当前帧的父帧(爷)当成它的父帧。
在这里插入图片描述

float KeyFrame::ComputeSceneMedianDepth(const int q)

评估当前关键帧场景深度
步骤一:获取每个地图点的世界位姿
步骤二:找出当前帧Z方向上的旋转和平移,求每个地图点在当前相机坐标系中的z轴位置,求平均值。

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaFX中的`KeyFrame`是一个时间轴上的关键帧,它定义了在某个时间点上要执行的操作。下面是`KeyFrame`的构造方法: ``` public KeyFrame(Duration time, EventHandler<ActionEvent> onFinished) public KeyFrame(Duration time, String name, EventHandler<ActionEvent> onFinished) ``` 第一个构造方法是最基本的,它需要一个`Duration`型的时间和一个`EventHandler<ActionEvent>`型的事件处理器作为参数。当时间轴上的时间达到指定的时间时,`KeyFrame`上的事件处理器就会被触发执行。 第二个构造方法还需要一个字符串型的名称作为参数,用于标识这个关键帧。这个名称可以在后续的代码中用来引用这个关键帧。 下面是一个使用`KeyFrame`的例子: ``` import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javafx.util.Duration; public class KeyFrameExample extends Application { @Override public void start(Stage primaryStage) { StackPane root = new StackPane(); // 创建一个时间轴,并添加一个关键帧 Timeline timeline = new Timeline(); timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(2), new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Hello, world!"); } })); // 播放时间轴 timeline.play(); Scene scene = new Scene(root, 300, 250); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } ``` 在这个例子中,我们创建了一个时间轴,并在其中添加了一个关键帧,当时间轴上的时间达到2秒时,就会执行`handle`方法中的代码,输出"Hello, world!"。然后我们启动了时间轴,这样它就开始按照设定的时间轴执行了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值