DBOW概要理解与记录

前言

DBOW作为一种视觉回环技术被广泛应用在各类VSLAM框架中,之前的经验主要集中在使用和抽象理解层面,近期花了一些时间仔细阅读了相关论文和源码,这里做一些记录。

两个关键概念

Vocabulary

通过预先训练得到的词汇库,以树状数据结构保存,便于后续查询,如下图黄色部分:
在这里插入图片描述

  • 训练过程:通过数据集提取每张图片feature构成一个feature集,将feature集进行按层级的kmeans++聚类(每一层都进行一次聚类,得到centroid node作为节点),最终获取到d层共w个words,每一个word根据在数据集中的频次计算其weight并保存,待后续使用。
  • 查询过程:从根节点开始,将待查询feature(f)与每层的node计算hamming distance,选择最小值的node继续往下,依次从上到下贯穿整棵树,直到叶子节点,就得到其对应的word。

Dataset

上图中的蓝色部分,在实际使用中,需要实时构建数据库,用于后续查找回环。

  • 构建数据库:采集到的每张图片提取全部feature,所有feature通过vocabulary查询获取对应word,所有word构成这张图片对应的Bowvector,同时,根据word的weight与单张图片中该word出现比例可以计算得到value,这些信息将会构成一张反向索引表(所有包含某个word的图片索引)和一张正向索引表(每张图片保护的word索引及alue),这两张表实际上就是数据库,用于后面提取历史keyframe对应的图片的Bowvector。

回环检测过程

  • 1、构建自己的vocabulary并保存,这一步一般可以省略,可以直接使用作者提供的一份vocabulary file,如果效果不佳,可以考虑自己构建。
  • 2、运行自己的VIO算法,每一个keyframe对应的图片加入到dataset,实时构建dataset,代码如下:
inline DBow::EntryId DBow::Database::AddEntry(const vector<float>& features)
{
	DBow::BowVector v;
	m_voc->Transform(features, v, false);
	return _AddEntry(v);
}

EntryId Database::_AddEntry(BowVector &v)
{
	VocParams::ScoringType norm;
	if(VocParams::MustNormalize(m_voc->Scoring(), norm)){
		// vectors are stored normalized if needed
		v.Normalize(norm);
	}

	EntryId eid = m_nentries;

	// update inverted file
	BowVector::const_iterator it;
	for(it = v.begin(); it != v.end(); it++){
		// eids are in ascending order in the index
		m_index[it->id].push_back(IFEntry(eid, it->value));
	}

	m_nentries++;

	return eid;
}
  • 3、每一个新的keyframe对应的图片,加入dataset查询回环,具体过程是,将图片提取全部feature并通过vocabulary转换得到Bowvector,通过dataset查询相关的历史keyframe,计算当前keyframe与历史keyframe对应Bowvector的loss,计算算法有很多种类,如下:
	switch(info.Parameters->Scoring){
		
		case VocParams::L1_NORM:
			doQueryL1(v, ret, max_results, info.Parameters->ScaleScore);
			break;

		case VocParams::L2_NORM:
			doQueryL2(v, ret, max_results, info.Parameters->ScaleScore);
			break;

		case VocParams::CHI_SQUARE:
			doQueryChiSquare(v, ret, max_results, info.Parameters->ScaleScore);
			break;

		case VocParams::KL:
			doQueryKL(v, ret, max_results, info.Parameters->ScaleScore);
			break;

		case VocParams::BHATTACHARYYA:
			doQueryBhattacharyya(v, ret, max_results, info.Parameters->ScaleScore);
			break;

		case VocParams::DOT_PRODUCT:
			doQueryDotProduct(v, ret, max_results, info.Parameters->ScaleScore);
			break;
	}

得到score,对score进行排序获取candidates,如下:

void Database::doQueryL1(const BowVector &v, QueryResults &ret, 
						 const int max_results, const bool scale_score) const
{
	BowVector::const_iterator it;
	IFRow::const_iterator rit;
	QueryResults::iterator qit;
	
	for(it = v.begin(); it != v.end(); it++){
		WordId wid = it->id;
		WordValue qvalue = it->value;
		
		const IFRow& row = m_index[wid];

		for(rit = row.begin(); rit != row.end(); rit++){
			EntryId eid = rit->id;
			WordValue dvalue = rit->value;

			// scoring-dependent value
			double value = fabs(qvalue - dvalue) - fabs(qvalue) - fabs(dvalue);

			// check if this entry is already in the returning vector
			qit = find(ret.begin(), ret.end(), eid);

			if(qit == ret.end()){
				// insert
				ret.push_back(Result(eid, value));
			}else{
				// update
				qit->Score += value; 
			}
		} // for each inverted row 
	} // for each word in features	

	// resulting "scores" are now in [-2 best .. 0 worst]
	
	// sort vector in ascending order
	// (scores are inverted now --the lower the better--)
	sort(ret.begin(), ret.end());

	// cut vector
	if((int)ret.size() > max_results) ret.resize(max_results);

	// complete score
	// ||v - w||_{L1} = 2 + Sum(|v_i - w_i| - |v_i| - |w_i|) 
	//		for all i | v_i != 0 and w_i != 0 
	// (Nister, 2006)
	if(scale_score){
		for(qit = ret.begin(); qit != ret.end(); qit++) 
			qit->Score = -qit->Score/2.0;
	}else{
		for(qit = ret.begin(); qit != ret.end(); qit++) 
			qit->Score = 2.0 + qit->Score;
	}
}

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

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

相关文章

VR全景餐厅,为餐饮老板开启了新纪元

在近两年的“元宇宙”概念的催生下&#xff0c;VR全景技术逐渐渗透到我们生活的方方面面&#xff0c;从舌尖到指尖、从田间到车间、从衣食住行到娱乐消费等&#xff0c;越来越多的行业、领域开始引入VR全景了&#xff0c;并在各自的垂直领域开拓了VR全景新时代。 而一直以来&am…

强化学习问题(7)--- Python和Pytorch,Tensorflow的版本对应

1.问题 之前下载的python3.8&#xff0c;在对应Pytorch和Tensorflow时没太在意版本&#xff0c;在运行一些代码时&#xff0c;提示Pytorch和Tensorflow版本过高&#xff0c;直接降下来&#xff0c;有时候又和Python3.8不兼容&#xff0c;所以又在虚拟环境搞一个Pyhon3.7&#x…

超简洁ubuntu linux 安装 cp2k

文章目录 打开下载网址解压接下来的步骤讲解 将解压的包移到对应路径下最后运行 打开下载网址 需要从github下载&#xff1a;下载网址 两个都可以从windows下先下载&#xff0c;再复制到linux中&#xff0c; 如果不能复制&#xff0c;右键这两个&#xff0c;复制链接&#xf…

项目总结-新增商品-Pagehelper插件分页查询

&#xff08;1&#xff09;新增商品 工具类&#xff1a; /** * Title: FileUtils.java * Package com.qfedu.common.utils * Description: TODO(用一句话描述该文件做什么) * author Feri * date 2018年5月29日 * version V1.0 */ package com.gdsdxy.common.u…

Android Studio中配置aliyun maven库

当下载第三方库失败的时候&#xff0c;通过Android Studio中配置aliyun maven库&#xff0c;达到正常下载库效果 在项目的根build.gradle里面&#xff08;不是module&#xff09;buildscriptde对应位置添加配置&#xff1a; maven { url https://maven.aliyun.com/repository/…

优优嗨聚集团:抖音外卖,美食与文化的完美结合

在今天的数字化时代&#xff0c;外卖行业正在迅速发展&#xff0c;而抖音外卖的出现&#xff0c;更是引领了外卖行业的新潮流。抖音外卖不仅满足了人们对美食的追求&#xff0c;还让人们在享受美食的同时&#xff0c;感受到了浓厚的文化氛围。 抖音外卖是抖音平台推出的一项全新…

Google Authenticator认证密钥从手机App中同步到Chrome浏览器插件中

前言 现在很多重要的项目都用了Google Authenticator来做安全认证&#xff0c;比如Github&#xff0c;Jumpserver等等&#xff0c;但每次认证登录时候&#xff0c;都得掏出来手机看token码就比较麻烦。 还好 Google Authenticator 有 Chrome 浏览器插件&#xff0c;可以直接同…

YOLOv8改进实战 | 更换损失函数之MPDIOU(2023最新IOU)篇

前言 YOLOv8官方默认损失函数采用的是CIoU。本章节主要介绍如何将MPDIoU损失函数应用于目标检测YOLOv8模型。 目录 一、MPDIoU二、代码实现添加损失函数更换损失函数一、MPDIoU 论文链接:MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression MPDIoU是一种基于…

打破总分行数据协作壁垒,DataOps在头部股份制银行的实践|案例研究

从银行开始建设数据仓库至今已近20年&#xff0c;当前各银行机构在数据能力建设中面临诸多困扰&#xff1a;如何保证数据使用时的准确性&#xff1f;如何让数据敏捷响应业务变化&#xff1f;如何让更多的业务人员使用数据&#xff1f; 这些问题极大影响了经营指标的达成与业务…

分布式事务——CAP理论 解决分布式事务的思路 Seata组件初识 和 部署

前言 事务(TRANSACTION)是一个不可分割的逻辑单元&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体向系统提交&#xff0c;要么都执行、要么都不执行。 事务作为系统中必须考虑的问题&#xff0c;无论是在单体项目还是在分布式项目中都需要进行…

Python机器学习17——Xgboost和Lightgbm结合分位数回归(机器学习与传统统计学结合)

最近XGboost支持分位数回归了&#xff0c;我看了一下&#xff0c;就做了个小的代码案例。毕竟学术市场上做这种新颖的机器学习和传统统计学结合的方法还是不多&#xff0c;算的上创新&#xff0c;找个好数据集可以发论文。 代码实现 导入包 import numpy as np import pandas…

uni-app医院智能导诊系统源码

随着科技的迅速发展&#xff0c;人工智能已经逐渐渗透到我们生活的各个领域。在医疗行业中&#xff0c;智能导诊系统成为了一个备受关注的应用。本文将详细介绍智能导诊系统的概念、技术原理以及在医疗领域中的应用&#xff0c;分析其优势和未来发展趋势。 智能导诊系统通过人工…

如何训练Embedding Model

BGE的技术亮点&#xff1a; 高效预训练和大规模文本微调&#xff1b;在两个大规模语料集上采用了RetroMAE预训练算法&#xff0c;进一步增强了模型的语义表征能力&#xff1b;通过负采样和难负样例挖掘&#xff0c;增强了语义向量的判别力&#xff1b;借鉴Instruction Tuning的…

中央设备状态监控系统CMS如何帮助半导体晶圆厂提高产品良率

中央设备状态监控系统&#xff08;CMS&#xff09;在半导体晶圆厂中扮演着关键角色&#xff0c;帮助企业提高产品的良率。本文将介绍CMS是什么、当前半导体晶圆厂产品良率面临的挑战&#xff0c;并重点探讨CMS如何通过实时数据监控、故障预测和预警、以及统计分析和过程改进等方…

【论文阅读】(2023TPAMI)PCRLv2

目录 AbstractMethodMethodnsU-Net中的特征金字塔多尺度像素恢复多尺度特征比较从多剪切到下剪切训练目标 总结 Abstract 现有方法及其缺点&#xff1a;最近的SSL方法大多是对比学习方法&#xff0c;它的目标是通过比较不同图像视图来保留潜在表示中的不变合判别语义&#xff…

SENet 学习

ILSVRC 是一个比赛&#xff0c;全称是ImageNet Large-Scale Visual Recognition Challenge&#xff0c;平常说的ImageNet比赛指的是这个比赛。 使用的数据集是ImageNet数据集的一个子集&#xff0c;一般说的ImageNet&#xff08;数据集&#xff09;实际上指的是ImageNet的这个子…

day01_matplotlib_demo

文章目录 折线图plot多个绘图区绘制数学函数图像散点图scatter柱状图bar直方图histogram饼图pie总结 折线图plot import matplotlib.pyplot as pltplt.figure(figsize(15, 6), dpi80) plt.plot([1, 0, 9], [4, 5, 6]) plt.show()### 展现一周天气温度情况 # 创建画布 plt.figu…

NewStarCTF2023week4-More Fast(GC回收)

打开链接&#xff0c;存在很多个类&#xff0c;很明显是php反序列化漏洞利用&#xff0c;需要构造pop链 &#xff0c; 关于pop链构造的详细步骤教学&#xff0c;请参考我之前的博客&#xff0c;真的讲得很详细也容易理解&#xff1a; http://t.csdnimg.cn/wMYNB 如果你是刚接…

Echarts柱状图渐变色问题变通

问题背景 设计稿中给出了如下图的效果&#xff0c;在柱状图的最上面给出了一个白色的小块&#xff0c;起初我一直在思考亦或者搜索相关的问题&#xff1a;如何在Echarts柱状图顶部实现一个24*4的白色矩形块。始终不得其解&#xff0c;在一个吃饭的瞬间冒出来一个想法是否可以用…

MySQL数据xtrabackup物理备份方法

目录 一、物理备份的方式二、xtrabackup物理备份1.安装xtrabackup2.完整备份/恢复流程3.增量备份流程4.差异备份流程5.物理备份总结 一、物理备份的方式 1.完整备份 每次对数据进行完整的备份&#xff0c;即对整个数据库的备份、数据库结构和文件结构的备份&#xff0c;保存的…