第五篇 openvslam建圖與優化模塊梳理


建圖模塊

mapping_module在初始化系統的時候進行實例化,在構建實例的時候會實例化local_map_cleaner和local_bundle_adjuster。系統啟動的時候會在另外一個線程中啟動該模塊。

// src/openvslam/system.cc:78
mapper_ = new mapping_module(map_db_, camera_->setup_type_ == camera::setup_type_t::Monocular);

// src/openvslam/system.cc:123
mapping_thread_ = std::unique_ptr<std::thread>(new std::thread(&openvslam::mapping_module::run, mapper_));

對新增的關鍵幀進行建圖

// src/openvslam/mapping_module.cc:128
void mapping_module::mapping_with_new_keyframe()
對新增的關鍵幀進行建圖mapping_with_new_keyframe
    取出隊列中最早放入的關鍵幀
    設置原始關鍵幀ID
    將新關鍵幀保存入數據庫store_new_keyframe
        計算當前關鍵幀的BoW特征向量
        獲取當前關鍵幀的lm
        如果當前關鍵幀可以觀測到該lm,將lm添加入local_map_cleaner的fresh_landmarks中
        否則
            添加lm的觀測
            更新lm幾何信息
            計算lm的描述子
        更新圖連接update_connections
            獲取圖關鍵幀所有lm
            統計出共視關鍵幀以及共視lm數量情況,篩選出共視lm大於15的關鍵幀weight_covisibility_pairs
            尋找出共視lm數量最多的關鍵幀當做最近的共視關鍵幀
            圖中添加連接add_connection
            對weight_covisibility_pairs進行降序排列,更新ordered_covisibilities_和ordered_weights_
            更新生成樹。最近的共視關鍵幀設置為父樹,當前關鍵幀為子樹
        存儲關鍵幀
    去除冗余的lm(remove_redundant_landmarks)
        移除的邏輯
        1. observed_ratio小於觀測門限,需要從局部地圖buffer和數據庫中移除;
        2. 如果lm被添加之后一段時間內,被觀測到的其他幀觀測到的次數<=2,則認為時無效幀,需要從局部地圖buffer和數據庫中移除;
        3. 如果lm被添加之后一段時間內被多次觀測到,則認為該lm有效,只從局部地圖buffer中移除;
    依據當前關鍵幀和共視關鍵幀重新三角化lm(create_new_landmarks)
        獲取當前關鍵幀權重高的共視關鍵幀
        逐個計算當前關鍵幀與共視關鍵幀之間的本質矩陣
        利用本質矩陣計算出兩關鍵幀lm的匹配情況
        三角化匹配的lm,三角化成功的點將添加入庫
    檢測處理重復的lm(update_new_keyframe)
        獲取兩層共視關鍵幀
        融合重復的lm(fuse_landmark_duplication)
            獲取當前幀的lm
            逐個共視關鍵幀去重(replace_duplication)
                如果lm沒有被共視關鍵幀觀測到
                將lm重投影至該共視關鍵幀,提取共視關鍵幀投影區域附近的特征點,如果相似度很高且重投影誤差很小,
                使用共視關鍵幀的lm點取代當前的lm,如果共視關鍵幀沒有對應的lm則把當前lm添加到共視關鍵幀
            獲取所有共視關鍵幀的lm集合再次進行去重(replace_duplication)
                這里和上面去重輸入參數是不一樣的,這里的關鍵幀是當前關鍵幀,lm是共視關鍵幀lm集合
        更新當前幀lm幾何信息和圖連接
    進行局部地圖BA(local_bundle_adjuster)
    祛除冗余的關鍵幀remove_redundant_keyframes
        獲取當前關鍵幀的共視關鍵幀
        逐個共視關鍵幀計算冗余觀測count_redundant_observations
            獲取當前共視關鍵幀的lm
            逐個lm統計其共視關鍵幀數量,如果不小於3個就認為lm是冗余的num_redundant_obs++
            lm深度有效就認為是有效的lm,num_valid_obs++
        如果num_redundant_obs / num_valid_obs > 0.9,則認為該共視關鍵幀是冗余的,移除掉
將新的關鍵幀發送給全局優化模塊隊列

觀測門限清理

在跟蹤模塊優化局部地圖optimize_current_frame_with_local_map時,首先會統計出當前幀可以被觀測到的lm,會調用lm->increase_num_observable(),位姿優化后統計inlier的lm,調用lm->increase_num_observed(),因此num_observed_記錄的是跟蹤過程中真正有效的lm,num_observable_記錄的是局部地圖中可以被當前幀觀測到的lm,如果num_observed_ / num_observable_的值很小的話,說明該lm對位姿評估沒有太大意義,可以從局部地圖buffer和數據庫中清除掉。

// src/openvslam/tracking_module.cc:340
bool tracking_module::optimize_current_frame_with_local_map()

全局優化模塊

和建圖模塊一樣, 全局優化模塊global_optimization_module在初始化系統的時候進行實例化,在構建實例的時候會實例化graph_optimizer、loop_detector和loop_bundle_adjuster。系統啟動的時候會在另外一個線程中啟動該模塊。

// src/openvslam/system.cc:80
global_optimizer_ = new global_optimization_module(map_db_, bow_db_, bow_vocab_, camera_->setup_type_ != camera::setup_type_t::Monocular);

// src/openvslam/system.cc:124
global_optimization_thread_ = std::unique_ptr<std::thread>(new std::thread(&openvslam::global_optimization_module::run, global_optimizer_));

run
    取出隊列中最早放入的關鍵幀
    設置標記保證在回環檢測和校正期間關鍵幀不被擦除
    將關鍵幀傳入回環檢測模塊
    檢測回環候選detect_loop_candidates
        回環檢測功能被禁用或者剛剛被校正過,則不需要檢測回環候選,直接將關鍵幀添加到bow_db
        1. 通過查詢BoW數據庫來搜索循環候選者
            在查詢之前,計算當前關鍵幀和每個共視關鍵幀之間的BoW相似性的最小分數
            獲取回環候選acquire_loop_candidates
                獲取與當前關鍵幀相連的關鍵幀集合(通過graph_node)
                統計當前關鍵幀和其他關鍵幀共享單詞數量情況
                將最大共享單詞數量*0.8作為最小共享單詞門限
                計算共享單詞數滿足條件的候選關鍵幀於當前關鍵幀的bow得分
                挑選出不大於最小分數候選關鍵幀對兒score_keyfrm_pairs
                計算每個候選關鍵幀(score_keyfrm_pairs)鄰域的得分並取總和best_total_score
                大於best_total_score*0.75才為有效的候選幀
            沒有回環候選幀將當前關鍵幀添加到BoW database
        2. 尋找連續關鍵幀集合find_continuously_detected_keyframe_sets
            逐個查看回環候選關鍵幀
                獲取相連的關鍵幀集合
                檢測與之前連續關鍵幀集合是否相連,如果相連,添加入當前連續關鍵幀集合
        3. 將連接數大於2的關鍵幀放入回環候選
        4. 保存當前連續關鍵幀集合以便下次使用
    如果當前關鍵沒有找到回環候選,那么當前幀是可以被刪除的
    驗證回環並且從中選出一個validate_candidates
        使用線性和非線性的方式評估當前關鍵幀和候選關鍵幀的sim3,挑選出回環候選幀
    校正回環correct_loop
        獲取當前關鍵幀的共視關鍵幀
        獲取回環校正前的共視關鍵幀的Sim3s_nw
        計算回環校正后的共視關鍵幀的Sim3s_nw
        校正共視關鍵幀中的lm的位置信息
        校正共視關鍵幀的位姿信息
        處理回環融合帶來的重復lm(replace_duplicated_landmarks)
            用回環候選關鍵中的lm替換當前幀中的lm
            使用match::fuse檢測重復的關鍵點
        獲取新的連接關系,進行圖優化sim3
            優化的變量只有關鍵幀位姿,優化完成后使用優化的結果調整landmark
        添加回環邊
        最后進行loop BA

問題

  1. 搞清楚線性和非線性sim3;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM