关于VINS-Fusion中loop-fusion中使用brief_k10L6.bin文件的问题

一.问题说明

在小车上部署好VINS-Fusion后,进行实物测试。使用命令

rosrun loop-fusion loop-fusion-node config.yaml

时发生报错:

config_file: euroc_stereo_imu_config2.yaml
vocabulary_file/home/amov/catkin_vinfusion/src/VINS-Fusion-master/loop_fusion/../support_files/brief_k10L6.bin
段错误 (核心已转储)

二.判断问题

找到代码块中报错的位置是VINS_Fusion/loop_fusion/src/pose_graph.cpp 的 64行

void PoseGraph::loadVocabulary(std::string voc_path)
{
    voc = new BriefVocabulary(voc_path);
    db.setVocabulary(*voc, false, 0);
}

中的BriefVocabulary 构造函数报错。再三查看,确认路径设置是没有问题的。
使用代码跳转功能进入到该构造函数中去,地址为:loop_fusion/src/ThirdParty/DBoW/TemplatedVocabulary.h
使用输出调试,定位到代码出错位置,是loadBin方法中对于读取文件中的循环代码块中:

  m_nodes.resize(voc.nNodes + 1); // +1 to include root
  cout<<"m_nodes size is:"<<m_nodes.size()<<endl;
  m_nodes[0].id = 0;

  for(unsigned int i = 0; i < voc.nNodes; ++i)
  {
    NodeId nid = voc.nodes[i].nodeId;
    NodeId pid = voc.nodes[i].parentId;
    WordValue weight = voc.nodes[i].weight;
    // std::cerr << "Invalid node ID: nid=" << nid << ", pid=" << pid << ", at index i=" << i << std::endl;
    // if (nid >= m_nodes.size() || pid >= m_nodes.size()) {
    //     std::cerr << "Invalid node ID: nid=" << nid << ", pid=" << pid << ", at index i=" << i << std::endl;
    //     continue;
    // }
    m_nodes[nid].id = nid;
    m_nodes[nid].parent = pid;
    m_nodes[nid].weight = weight;
    m_nodes[pid].children.push_back(nid);
    if (nid >= m_nodes.size() || pid >= m_nodes.size()) {
        std::cerr << "Invalid node ID: nid=" << nid << ", pid=" << pid << ", at index i=" << i << std::endl;
        continue;
    }
      if (voc.nodes[i].descriptor == nullptr) {
        std::cerr << "Invalid descriptor pointer at index i=" << i << std::endl;
        continue;
    }
    // Sorry to break template here
    m_nodes[nid].descriptor = boost::dynamic_bitset<>(voc.nodes[i].descriptor, voc.nodes[i].descriptor + 4);
    
    if (i < 5) {
      std::string test;
      boost::to_string(m_nodes[nid].descriptor, test);
      //cout << "descriptor[" << i << "] = " << test << endl;
    }
  }

使用代码:

if (nid >= m_nodes.size() || pid >= m_nodes.size()) {
   std::cerr << "Invalid node ID: nid=" << nid << ", pid=" << pid << ", at index i=" << i << std::endl;
   continue;
}

发现大量不合理数据,其中nid 和 pid的值远远大于m_nodes设定的范围。

在这里插入图片描述
判断是文件出问题了,于是从u盘中重新复制一份brief_k10L6.bin 可是问题依旧没有解决。刚好我的台式机上也部署了VINS-Fusion, 其中loop-fuison 是可以运行的,找到相应的这个循环的代码块进行输出:
在这里插入图片描述
这里输出正常,而且通过了循环代码块,表明源文件是正常的。我突然想到一种可能,不会不是因为把该文件放入到u盘上的时候这个文件的内容发生了改变导致的?所以打算使用scp命令复制该文件。

三. 解决办法

将硬件平台和电脑主机连接上同一网段,使用scp命令进行文件的传输:

scp -r brief_k10L6.bin username@remote_host:/path/to/remote/destination

将文件重传一遍。继续运行loop_fuison,发现这个错误消除。
在这里插入图片描述
对于上图中,下面的配置文件位置出错的问题,参考博客:

https://blog.youkuaiyun.com/qq_52710816/article/details/125046226

将loop-fusion中的pose_graph_node.cpp 大约448行的 cam0Path进行修改:

	std::string cam0Calib;
    fsSettings["cam0_calib"] >> cam0Calib;
    // 修改这里
    // std::string cam0Path = configPath + "/" + cam0Calib;
     std::string cam0Path =  cam0Calib;

重新编译,在配置文件目录下运行loop_fusion即可。

<think>我们正在讨论VINS-Mono中的brief_k10L6.bin词袋文件。根据引用内容,我们可以知道: 1. 引用[1]提到VINS-mono中的DBoW专为Brief特征写了读取.bin文件的加载函数,并添加了头文件"VocabularyBinary.hpp"和boost库的bitset支持。 2. 引用[2]指出在pose_graph_node.cpp中使用了DBoW2进行回环检测,回环检测的方法是图像与数据库的比较(与ORB-SLAM的图像与图像直接比较不同)。 3. 引用[3]介绍了一个类BriefExtractor,它用于计算图像的Brief描述子。 4. 引用[4]说明了pose_graph中用户可以通过键盘控制保存位姿图或开始新的序列。 现在,用户的问题是关于brief_k10L6.bin词袋文件的作用、适用场景以及是否可省略。 分析: - brief_k10L6.bin是一个预先训练好的词袋模型(Vocabulary),它使用BRIEF描述子构建,其中k10表示聚类中心有10层(树深度为10),L6表示每个非叶子节点有6个分支(即k=6的k-means树)。 -VINS-Mono中,该词袋文件用于回环检测模块(pose_graph)。当系统运行到回环检测线程时,它会提取当前图像的BRIEF描述子,然后通过词袋模型将图像描述成一个向量(词袋向量),进而与数据库中的历史图像进行相似度比较,以检测回环。 作用: 1. **高效回环检测**:词袋模型将图像表示为一个稀疏的向量(视觉词袋向量),通过比较向量之间的相似度(如L1距离)可以快速找到候选回环帧,避免了暴力匹配的时间消耗。 2. **提供回环候选**:当当前帧与历史帧的词袋向量相似度超过一定阈值时,认为可能发生回环,然后通过几何验证(如RANSAC计算基础矩阵)来确认回环。 适用场景: - 该词袋文件是专门为BRIEF描述子设计的,因此只适用于使用BRIEF描述子的场景。在VINS-Mono中,前端使用的是BRIEF描述子(引用[3]中的BriefExtractor类),所以回环检测模块必须使用这个词袋文件- 如果更换了特征描述子(如ORB、SIFT等),则需要重新训练相应的词袋模型。 是否可以省略? - 不能省略。因为回环检测模块依赖于词袋模型来快速检索相似图像。如果没有词袋文件,系统将无法进行回环检测,导致无法修正累积误差,从而影响整个SLAM系统的精度。 - 但是,如果不需要回环检测功能(例如在短时间、小范围运行),可以在配置文件中关闭回环检测(设置loop_closure参数为0),这样就不会加载和使用词袋文件。但这样系统将无法消除累积误差。 总结: - brief_k10L6.binVINS-Mono回环检测模块必需的词袋文件,用于加速回环检测过程。 - 它适用于使用BRIEF描述子的场景,并且不能省略(除非关闭回环检测功能)。 根据用户提供的引用,我们还可以看到: - 引用[1]说明了VINS-Mono修改了DBoW2以支持读取二进制词袋文件.bin格式),因此必须使用这种格式的词袋文件- 引用[2]提到在pose_graph_node.cpp中使用了DBoW2进行图像与数据库的比较,这进一步证实了词袋文件在回环检测中的核心作用。 因此,回答如下:</think>### VINS-Mono中`brief_k10L6.bin`词袋文件解析 #### 一、核心作用 1. **回环检测加速** -文件是预训练的**视觉词典**(Vocabulary),采用BRIEF特征描述子构建 - 通过k-means树结构(k=6分支,深度10层)将图像特征映射到高维词袋空间 - 实现帧间相似度的**快速比对**(避免暴力匹配),时间复杂度从$O(n^2)$降至$O(\log n)$[^2] 2. **闭环验证基础** - 当系统检测到潜在闭环时(如轨迹重叠),词袋向量提供**初步相似性判断** - 与几何验证(如RANSAC)结合,形成两级闭环检测机制: $$ \text{闭环决策} = \Phi(\text{词袋相似度}) \land \Psi(\text{几何一致性}) $$[^4] #### 二、适用场景分析 | 场景类型 | 是否必需 | 原因说明 | |----------|----------|----------| | **长时序SLAM** | ✔️ 必需 | 消除累积误差,依赖闭环校正轨迹 | | **小范围场景** | ✘ 可省略 | 短时运行累积误差小(需关闭`LOOP_CLOSURE`参数) | | **动态环境** | ⚠️ 有限效果 | 环境变化可能导致词袋匹配失效 | | **更换特征类型** | ✘ 不可用 | 仅适配BRIEF描述子(需重训词典)[^3] | #### 三、是否可省略 1. **技术可行性** - 通过修改`pose_graph_node.cpp`源码可跳过加载: ```cpp // 注释掉词典加载代码 // posegraph.loadVocabulary(dict_path); ``` - 同时关闭回环检测标志:`LOOP_CLOSURE = false`[^4] 2. **性能影响** - **定位精度下降**:长距离导航时漂移误差无法校正 - **内存/CPU占用降低**:词典文件约50-100MB,实时匹配消耗10-15% CPU资源 - **系统鲁棒性削弱**:依赖前端VO,运动模糊场景易失败 #### 四、典型应用流程 ```mermaid graph LR A[新图像帧] --> B{LOOP_CLOSURE?} B -->|开启| C[提取BRIEF特征] C --> D[查询brief_k10L6.bin词典] D --> E[生成词袋向量] E --> F[数据库相似度搜索] F -->|匹配成功| G[几何验证] G -->|验证通过| H[闭环优化位姿图] B -->|关闭| I[纯视觉里程计模式] ``` ### 总结建议 - **必需使用场景**:大范围建图、长期定位任务(仓储AGV、无人机勘测) - **可省略场景**:短时演示、已知环境小范围导航 - **替代方案**:若需更换特征类型(如ORB),需用DBoW2工具重训词典: ```bash ./dbow2_trainer -t BRIEF -d 6 -l 10 -o new_voc.bin ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值