修改orbslam2代码,加载二进制词典文件,加速词典加载速度

修改orbslam2代码,加载二进制词典文件,加速词典加载速度

0.在ORB_SLAM2下创建tools文件夹,放入bin_vocabulary.cc程序

#include <time.h>

#include "ORBVocabulary.h"
using namespace std;

bool load_as_text(ORB_SLAM2::ORBVocabulary* voc, const std::string infile);

void load_as_xml(ORB_SLAM2::ORBVocabulary* voc, const std::string infile);

void load_as_binary(ORB_SLAM2::ORBVocabulary* voc, const std::string infile);

void save_as_text(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile);

void save_as_xml(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile);

void save_as_binary(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile);


int main(int argc, char **argv) {
  cout << "BoW load/save benchmark" << endl;
  ORB_SLAM2::ORBVocabulary* voc = new ORB_SLAM2::ORBVocabulary();

  load_as_text(voc, "Vocabulary/ORBvoc.txt");
  save_as_binary(voc, "Vocabulary/ORBvoc.bin");

  return 0;
}



bool load_as_text(ORB_SLAM2::ORBVocabulary* voc, const std::string infile) {
  clock_t tStart = clock();
  bool res = voc->loadFromTextFile(infile);
  printf("Loading fom text: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
  return res;
}

void load_as_xml(ORB_SLAM2::ORBVocabulary* voc, const std::string infile) {
  clock_t tStart = clock();
  voc->load(infile);
  printf("Loading fom xml: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}

void load_as_binary(ORB_SLAM2::ORBVocabulary* voc, const std::string infile) {
  clock_t tStart = clock();
  voc->loadFromBinaryFile(infile);
  printf("Loading fom binary: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}



void save_as_text(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile) {
  clock_t tStart = clock();
  voc->saveToTextFile(outfile);
  printf("Saving as text: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}

void save_as_xml(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile) {
  clock_t tStart = clock();
  voc->save(outfile);
  printf("Saving as xml: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}

void save_as_binary(ORB_SLAM2::ORBVocabulary* voc, const std::string outfile) {
  clock_t tStart = clock();
  voc->saveToBinaryFile(outfile);
  printf("Saving as binary: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}

1.修改ORB_SLAM2下的CMakelist.txt

在末尾添加可执行文件
# Build tools
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/tools)
add_executable(bin_vocabulary tools/bin_vocabulary.cc)
target_link_libraries(bin_vocabulary ${PROJECT_NAME})

2.修改build.sh

在末尾添加

cd ..
echo "Converting vocabulary to binary"
./tools/bin_vocabulary

3.修改System.cc中加载词典的函数
DBow2中TemplatedVocabulary.h中添加词典加载方式
函数声明:

 bool loadFromBinaryFile(const std::string &filename);
 void saveToBinaryFile(const std::string &filename) const;  

函数定义:

template<class TDescriptor, class F>
bool TemplatedVocabulary<TDescriptor,F>::loadFromBinaryFile(const std::string &filename) {
  fstream f;
  f.open(filename.c_str(), ios_base::in|ios::binary);
  unsigned int nb_nodes, size_node;
  f.read((char*)&nb_nodes, sizeof(nb_nodes));
  f.read((char*)&size_node, sizeof(size_node));
  f.read((char*)&m_k, sizeof(m_k));
  f.read((char*)&m_L, sizeof(m_L));
  f.read((char*)&m_scoring, sizeof(m_scoring));
  f.read((char*)&m_weighting, sizeof(m_weighting));
  createScoringObject();

  m_words.clear();
  m_words.reserve(pow((double)m_k, (double)m_L + 1));
  m_nodes.clear();
  m_nodes.resize(nb_nodes+1);
  m_nodes[0].id = 0;
  char buf[size_node]; int nid = 1;
  while (!f.eof()) {
	f.read(buf, size_node);
	m_nodes[nid].id = nid;
	// FIXME
	const int* ptr=(int*)buf;
	m_nodes[nid].parent = *ptr;
	//m_nodes[nid].parent = *(const int*)buf;
	m_nodes[m_nodes[nid].parent].children.push_back(nid);
	m_nodes[nid].descriptor = cv::Mat(1, F::L, CV_8U);
	memcpy(m_nodes[nid].descriptor.data, buf+4, F::L);
	m_nodes[nid].weight = *(float*)(buf+4+F::L);
	if (buf[8+F::L]) { // is leaf
	  int wid = m_words.size();
	  m_words.resize(wid+1);
	  m_nodes[nid].word_id = wid;
	  m_words[wid] = &m_nodes[nid];
	}
	else
	  m_nodes[nid].children.reserve(m_k);
	nid+=1;
  }
  f.close();
  return true;
}


// --------------------------------------------------------------------------

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::saveToBinaryFile(const std::string &filename) const {
  fstream f;
  f.open(filename.c_str(), ios_base::out|ios::binary);
  unsigned int nb_nodes = m_nodes.size();
  float _weight;
  unsigned int size_node = sizeof(m_nodes[0].parent) + F::L*sizeof(char) + sizeof(_weight) + sizeof(bool);
  f.write((char*)&nb_nodes, sizeof(nb_nodes));
  f.write((char*)&size_node, sizeof(size_node));
  f.write((char*)&m_k, sizeof(m_k));
  f.write((char*)&m_L, sizeof(m_L));
  f.write((char*)&m_scoring, sizeof(m_scoring));
  f.write((char*)&m_weighting, sizeof(m_weighting));
  for(size_t i=1; i<nb_nodes;i++) {
	const Node& node = m_nodes[i];
	f.write((char*)&node.parent, sizeof(node.parent));
	f.write((char*)node.descriptor.data, F::L);
	_weight = node.weight; f.write((char*)&_weight, sizeof(_weight));
	bool is_leaf = node.isLeaf(); f.write((char*)&is_leaf, sizeof(is_leaf)); // i put this one at the end for alignement....
  }
  f.close();
}
//-----------------------------------------------------------------------

4.修改src下部分代码
src/PnPsolver.cc

  vAvailableIndices[idx] = vAvailableIndices.back();
  修改为
   vAvailableIndices[randi] = vAvailableIndices.back();

src/System.cc

最后一个头文件末添加:
#include <time.h>

bool has_suffix(const std::string &str, const std::string &suffix) {
  std::size_t index = str.find(suffix, str.size() - suffix.size());
  return (index != std::string::npos);
}

在mpVocabulary = new ORBVocabulary();前面添加 clock_t tStart = clock();

     clock_t tStart = clock();//添加时间----------
    // 加载txt文本文件,修改为加载bin二进制文件
    mpVocabulary = new ORBVocabulary();

注释bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);这句代码,改为下面代码

bool bVocLoad = false; // chose loading method based on file extension
    if (has_suffix(strVocFile, ".txt"))
	  bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);
	else
	  bVocLoad = mpVocabulary->loadFromBinaryFile(strVocFile);

在cout << “Vocabulary loaded!” << endl << endl;下面添加

    printf("Vocabulary loaded in %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);

我使用时自己训练的一个小型词典文件
Loading fom text: 3.47s
Saving as binary: 0.06s

运行数据集加载不同文件时
在这里插入图片描述
在这里插入图片描述

参考链接:https://blog.csdn.net/weixin_47074246/article/details/109185504

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/275043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手动创建idea SpringBoot 项目

步骤一&#xff1a; 步骤二&#xff1a; 选择Spring initializer -> Project SDK 选择自己的JDK版本 ->Next 步骤三&#xff1a; Maven POM ->Next 步骤四&#xff1a; 根据JDK版本选择Spring Boot版本 11版本及以上JDK建议选用3.2版本&#xff0c;JDK为11版本…

算法模板之单调栈和单调队列图文详解

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;算法模板、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️单调栈讲解1.1 &#x1f514;单调栈的定义1.2 &#x1f514;如何维护一个单…

JS + CSS 实现高亮关键词(不侵入DOM)

之前在做关键词检索高亮功能的时候&#xff0c;研究了下目前前端实现高亮的几种方式&#xff0c;第一就是替换dom元素实现高亮&#xff0c;第二就是利用浏览器新特性Css.highlights结合js选区与光标与CSS高亮伪类实现&#xff0c;实现功能如下&#xff1a; 一、页面布局 一个…

海德堡UV灯电源维修eta Plus Elc PE22-400-210

uv灯电源维修故障包括&#xff1a; 1、电压不稳&#xff1a;检查uv打印机的电压&#xff0c;设置一个稳压箱即可。 2、温度过高&#xff1a;uv打印机温度过高也会影响uv灯&#xff0c;可以更换为水冷式循环降温。 3、水箱里的信号线接触不好&#xff1a;将两边的信号线对调&…

Python爬虫|使用Selenium轻松爬取网页数据

1. 什么是selenium&#xff1f; Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作浏览器一样。支持的浏览器包括IE&#xff0c;Firefox&#xff0c;Safari&#xff0c;Chrome等。 Selenium可以驱动浏览器自动执…

SpringBoot+ShardingSphereJDBC实战(读写分离,分库分表,垂直拆分、水平拆分)附源码

参考&#xff1a;https://www.51cto.com/article/747736.html https://blog.csdn.net/qq_41581588/article/details/126966665 源码地址&#xff1a;gitgitee.com:jackXUYY/springboot-example.git 读写分离测试 我们启用后缀名为dev的配置文件&#xff0c;如下&#xff0c;…

Visual Studio 2013 中创建一个基于 Qt 的动态链接库:并在MFC DLL程序中使用

在本地已经安装好 Qt 的情况下&#xff0c;按照以下步骤在 Visual Studio 2013 中创建一个基于 Qt 的动态链接库&#xff1a; 一、新建 Qt 项目&#xff1a; 在 Visual Studio 中&#xff0c;选择 “文件” -> “新建” -> “项目…”。在 “新建项目” 对话框中&#…

51和32单片机读取FSR薄膜压力传感器压力变化

文章目录 简介线性电压转换模块51单片机读取DO接线方式51代码实验效果 32单片机读取AO接线方式32代码实验效果 总结 简介 FSR薄膜压力传感器是可以将压力变化转换为电阻变化的一种传感器&#xff0c;单片机可以读取然后作为粗略测量压力&#xff08;仅提供压力变化&#xff0c;…

超时控制:Go语言下的网络请求与时间赛跑

开场白&#xff1a;在互联网的世界里&#xff0c;我们经常要与各种API打交道。有时&#xff0c;这些API可能会因为各种原因而变得“慢条斯理”&#xff0c;这时&#xff0c;超时控制就显得尤为重要了。今天&#xff0c;我们就来聊聊如何在Go语言中实现HTTP请求的超时控制&#…

【JavaScript】DOM事件的传播机制

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

企业如何正确的云迁移,云迁移过程中需要注意哪几个点?

如今的企业比以往任何时候都能访问更多的数据。这些数据正在以惊人的速度增长&#xff0c;无论是数量还是变化量。无论是传统的分析还是机器学习和人工智能等前沿技术&#xff0c;将这些信息从所有信息源集中到云存储库对业务至关重要。 为什么进行迁移&#xff1f; 企业将数…

【JavaScript】异步解决方案的发展历程

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

Flink1.17实战教程(第二篇:DataStream API)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

mybatis快速批量插入工具类

代码示例&#xff1a; package com.ly.cloud.util; import java.util.List;import javax.annotation.PostConstruct; import javax.annotation.Resource;import com.google.common.collect.Lists; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.s…

C1189#error: WinSock.h has already been included解决方案

最近在做项目移植过程中遇到这个报错&#xff0c;解决了半天。简单记录下解决方案&#xff0c;以供给大家提供一个思路。 原因&#xff1a; 在工程中使用了Boot库之后&#xff0c;使用了socket、tcp相关的头文件&#xff0c;在其他地方还是包括了头文件<windows.h>&…

「Verilog学习笔记」超前进位加法器

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 超前进位加法器的实质是&#xff1a;对于输出的每一位Si 其实都可以用Si Ai ^ Bi ^ Cin来表示 我们需要做的只是判断加法结果的最高位该取几 例如本题中 输入的两个数A和B…

云手机:多开群控全天在线,提高效率的最佳之选

对于需要高效处理多项任务的用户&#xff0c;Ogphone云手机以其多开、群控和全天在线的强大功能&#xff0c;成为提升效率的理想选择。下文将详细介绍Ogphone云手机的这三种功能是如何提高效率的。 多开分身&#xff1a;高效工作利器 Ogphone云手机采用基于ARM架构服务器的运行…

如何用电源模块综合测试系统测试逆变器电源输出电压?

万用表测量逆变器电源输出电压的方法 1.调整万用表到直流电压测量模式 2.确定测量电压的量程&#xff0c;选择合适挡位&#xff0c;一般建议选择稍大于逆变器额定电压的量程。 3.连接万用表“COM”插头到测量线的负极(通常为黑色插孔)&#xff0c;连接红色插头到测量线的正极(通…

【开源】基于JAVA的智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代…

内网穿透的应用-开源表格工具APITable本地部署结合内网穿透实现公网访问

文章目录 前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台&#xff0c;是一款面向 API 的智能多维表格。它将复杂的可视化数据库、电子表格、实时在线协同、低代码开发技术四合为一&am…