关于TUM数据集

2、验证回环检测算法,需要有人工标记回环的数据集。然而人工标记回环是很不方便的,我们会考虑根据标准轨迹计算回环。即,如果轨迹中有两个帧的位姿非常相近,就认为它们是回环。请根据TUM数据集给出的标准轨迹,计算出一个数据集中的回环。这些回环的图像真的相似吗?

文章目录

      • TUM数据集资料_链接
      • TUM 数据集 使用Tips
      • 使用TUM数据集,并与标准轨迹进行比较
        • 数据集下载
        • 仅下载轨迹
        • !! 轨迹显示
          • 轨迹显示 Python3 仅处理了 位移信息
        • 根据标准轨迹计算回环
            • 新建 .txt文件 touch CMakeLists.txt
            • CMakeLists.txt文件 包含的内容

TUM数据集资料_链接

!!高翔博客上的相关内容

在这里插入图片描述
在这里插入图片描述

TUM数据集网址:https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download

TUM 数据集 使用Tips

【Ctrl + ‘+’】放大字体。 博客园的字体有点小。

普通人; 赚钱花钱
乐趣:搞科研 + 码代码
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
associate.py

#!/usr/bin/python
# Software License Agreement (BSD License)
#
# Copyright (c) 2013, Juergen Sturm, TUM
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of TUM nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Requirements: 
# sudo apt-get install python-argparse"""
The Kinect provides the color and depth images in an un-synchronized way. This means that the set of time stamps from the color images do not intersect with those of the depth images. Therefore, we need some way of associating color images to depth images.For this purpose, you can use the ''associate.py'' script. It reads the time stamps from the rgb.txt file and the depth.txt file, and joins them by finding the best matches.
"""import argparse
import sys
import os
import numpydef read_file_list(filename):"""Reads a trajectory from a text file. File format:The file format is "stamp d1 d2 d3 ...", where stamp denotes the time stamp (to be matched)and "d1 d2 d3.." is arbitary data (e.g., a 3D position and 3D orientation) associated to this timestamp. Input:filename -- File nameOutput:dict -- dictionary of (stamp,data) tuples"""file = open(filename)data = file.read()lines = data.replace(","," ").replace("\t"," ").split("\n") list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]list = [(float(l[0]),l[1:]) for l in list if len(l)>1]return dict(list)def associate(first_list, second_list,offset,max_difference):"""Associate two dictionaries of (stamp,data). As the time stamps never match exactly, we aim to find the closest match for every input tuple.Input:first_list -- first dictionary of (stamp,data) tuplessecond_list -- second dictionary of (stamp,data) tuplesoffset -- time offset between both dictionaries (e.g., to model the delay between the sensors)max_difference -- search radius for candidate generationOutput:matches -- list of matched tuples ((stamp1,data1),(stamp2,data2))"""first_keys = first_list.keys()second_keys = second_list.keys()potential_matches = [(abs(a - (b + offset)), a, b) for a in first_keys for b in second_keys if abs(a - (b + offset)) < max_difference]potential_matches.sort()matches = []for diff, a, b in potential_matches:if a in first_keys and b in second_keys:first_keys.remove(a)second_keys.remove(b)matches.append((a, b))matches.sort()return matchesif __name__ == '__main__':# parse command lineparser = argparse.ArgumentParser(description='''This script takes two data files with timestamps and associates them   ''')parser.add_argument('first_file', help='first text file (format: timestamp data)')parser.add_argument('second_file', help='second text file (format: timestamp data)')parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true')parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0)parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02)args = parser.parse_args()first_list = read_file_list(args.first_file)second_list = read_file_list(args.second_file)matches = associate(first_list, second_list,float(args.offset),float(args.max_difference))    if args.first_only:for a,b in matches:print("%f %s"%(a," ".join(first_list[a])))else:for a,b in matches:print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b])))# associate.py
python associate.py rgb.txt depth.txt

在这里插入图片描述

python associate.py rgb.txt depth.txt > associate.txt

在这里插入图片描述
在这里插入图片描述
draw_groundtruth.py

在这里插入图片描述

python draw_groundtruth.py

如何查找每个图像的真实位置呢?

python associate.py associate.txt groundtruth.txt > associate_with_groundtruth.txt

在这里插入图片描述

  • 存 associate.py
  • 试运行

使用TUM数据集,并与标准轨迹进行比较

数据集下载

TUM数据集网址:https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download

在这里插入图片描述

参考链接2

在这里插入图片描述

wget https://cvg.cit.tum.de/rgbd/dataset/freiburg1/rgbd_dataset_freiburg1_room.tgz
tar -xf rgbd_dataset_freiburg1_room.tgz
仅下载轨迹

TUM数据集网址:https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download
https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download
在数据集下载界面往下拉 或
在这里插入图片描述
在这里插入图片描述
点击进去,另存为。

https://cvg.cit.tum.de/data/datasets/rgbd-dataset/download#freiburg1_room 或直接复制这个链接,另存即可。

需要把轨迹的.txt的前3行注释删掉
在这里插入图片描述

!! 轨迹显示

trajectory.txt每一行的内容为: t i m e , t x , t y , t z , q x , q y , q z time, t_x,t_y,t_z,q_x, q_y, q_z time,tx,ty,tz,qx,qy,qz
time: 该位姿的记录时间
t \bm{t} t: 平移
q \bm{q} q: 旋转四元数

plotTrajectory.cpp

#include <pangolin/pangolin.h>
#include <Eigen/Core>
#include <unistd.h>// 本例演示了如何画出一个预先存储的轨迹using namespace std;
using namespace Eigen;// path to trajectory file
string trajectory_file = "../rgbd_dataset_freiburg1_desk-groundtruth.txt"; // 该文件和.cpp同一目录void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>>);int main(int argc, char **argv) {vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;ifstream fin(trajectory_file);if (!fin) {cout << "cannot find trajectory file at " << trajectory_file << endl;return 1;}while (!fin.eof()) {double time, tx, ty, tz, qx, qy, qz, qw;fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw;Isometry3d Twr(Quaterniond(qw, qx, qy, qz));Twr.pretranslate(Vector3d(tx, ty, tz));poses.push_back(Twr);}cout << "read total " << poses.size() << " pose entries" << endl;// draw trajectory in pangolinDrawTrajectory(poses);return 0;
}/*******************************************************************************************/
void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses) {// create pangolin window and plot the trajectorypangolin::CreateWindowAndBind("Trajectory Viewer", 1024, 768);glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000),pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0));pangolin::View &d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -1024.0f / 768.0f).SetHandler(new pangolin::Handler3D(s_cam));while (pangolin::ShouldQuit() == false) {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);d_cam.Activate(s_cam);glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glLineWidth(2);  //  修改 线的宽度for (size_t i = 0; i < poses.size(); i++) {// 画每个位姿的三个坐标轴Vector3d Ow = poses[i].translation();Vector3d Xw = poses[i] * (0.1 * Vector3d(1, 0, 0));Vector3d Yw = poses[i] * (0.1 * Vector3d(0, 1, 0));Vector3d Zw = poses[i] * (0.1 * Vector3d(0, 0, 1));glBegin(GL_LINES);glColor3f(1.0, 0.0, 0.0);glVertex3d(Ow[0], Ow[1], Ow[2]);glVertex3d(Xw[0], Xw[1], Xw[2]);glColor3f(0.0, 1.0, 0.0);glVertex3d(Ow[0], Ow[1], Ow[2]);glVertex3d(Yw[0], Yw[1], Yw[2]);glColor3f(0.0, 0.0, 1.0);glVertex3d(Ow[0], Ow[1], Ow[2]);glVertex3d(Zw[0], Zw[1], Zw[2]);glEnd();}// 画出连线for (size_t i = 0; i < poses.size(); i++) {glColor3f(0.0, 0.0, 0.0);glBegin(GL_LINES);auto p1 = poses[i], p2 = poses[i + 1];glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]);glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]);glEnd();}pangolin::FinishFrame();usleep(5000);   // sleep 5 ms}
}

CMakeLists.txt

include_directories("/usr/include/eigen3")find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})
add_executable(plotTrajectory plotTrajectory.cpp)
target_link_libraries(plotTrajectory ${Pangolin_LIBRARIES})
mkdir build && cd build
cmake ..
make 
./plotTrajectory

GIF获取步骤

rgbd_dataset_freiburg1_room-groundtruth.txt
在这里插入图片描述
包含了 旋转信息

rgbd_dataset_freiburg1_desk-groundtruth.txt
desk TXT数据连接

xwininfo
byzanz-record -x 72 -y 64 -w 1848 -h 893  -d 10 --delay=5 -c  /home/xixi/myGIF/test.gif

在这里插入图片描述

轨迹显示 Python3 仅处理了 位移信息

draw_groundtruth.py

#!/usr/bin/env python
# coding=utf-8import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3df = open("./rgbd_dataset_freiburg1_room-groundtruth.txt")
x = []
y = []
z = []
for line in f:if line[0] == '#': # 这里跳过了 注释行continuedata = line.split() x.append( float(data[1] ) )y.append( float(data[2] ) )z.append( float(data[3] ) )
ax = plt.subplot( 111, projection='3d')
ax.plot(x,y,z)
plt.show()

命令行:

python3 draw_groundtruth.py

在这里插入图片描述

根据标准轨迹计算回环

tum.cpp

在这里插入图片描述

#include <pangolin/pangolin.h>
#include <Eigen/Core>
#include <Eigen/Geometry> 
#include <unistd.h>using namespace std;
using namespace Eigen;// path to groundtruth file    ***记得删掉轨迹txt的前3行注释。保证首行即为轨迹数据 ***
string groundtruth_file = "../rgbd_dataset_freiburg1_room-groundtruth.txt"; //  且.txt文件和.cpp在同一目录
// 设置检测的间隔,使得检测具有稀疏性的同时覆盖整个环境
int delta = 15;   // 这里的值要是不适合,有时测不到回环
// 齐次变换矩阵差的范数,小于该值时认为位姿非常接近
double threshold = 0.4; int main(int argc, char **argv) {vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;vector<string> times;ifstream fin(groundtruth_file);if (!fin) {cout << "cannot find trajectory file at " << groundtruth_file << endl;return 1;}int num = 0;while (!fin.eof()) {string time_s;double tx, ty, tz, qx, qy, qz, qw;fin >> time_s >> tx >> ty >> tz >> qx >> qy >> qz >> qw;Isometry3d Twr(Quaterniond(qw, qx, qy, qz));Twr.pretranslate(Vector3d(tx, ty, tz));// 相当于从第150个位姿开始,这是因为标准轨迹的记录早于照片拍摄(前120个位姿均无对应照片)if (num > 120 && num % delta == 0){times.push_back(time_s);poses.push_back(Twr);}num++;}cout << "read total " << num << " pose entries" << endl;cout << "selected total " << poses.size() << " pose entries" << endl;//设置检测到回环后重新开始检测图片间隔数量cout << "**************************************************" << endl;cout << "Detection Start!!!" << endl;cout << "**************************************************" << endl;for (size_t i = 0 ; i < poses.size() - delta; i += delta){for (size_t j = i + delta ; j < poses.size() ; j++){Matrix4d Error = (poses[i].inverse() * poses[j]).matrix() - Matrix4d::Identity();if (Error.norm() < threshold){cout << "第" << i << "张照片与第" << j << "张照片构成回环" << endl;cout << "位姿误差为" << Error.norm() << endl;cout << "第" << i << "张照片的时间戳为" << endl << times[i] << endl;cout << "第" << j << "张照片的时间戳为" << endl << times[j] << endl;cout << "**************************************************" << endl;break;}} }cout << "Detection Finish!!!" << endl;cout << "**************************************************" << endl;return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)project(tum)  # 输出文件名 include_directories("/usr/include/eigen3")
find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})add_executable(tum tum.cpp)
target_link_libraries(tum ${Pangolin_LIBRARIES})

命令行窗口指令:

mkdir build  # 若是已建有,跳过这步
cd build
cmake ..
make 
./tum 

轨迹.txt文件里的时间和图片的不太一致,暂时不清楚怎么对应。
delta = 15:
在这里插入图片描述

delta = 20:
在这里插入图片描述

delta = 10: 获得更多组结果。

在这里插入图片描述
在这里插入图片描述
由于 图片读取间隔的原因,图片名称不完全对应。。

新建 .txt文件 touch CMakeLists.txt

在待创建.txt文件的目录下打开命令行窗口。

touch CMakeLists.txt

其它类型文件 亦可用。

CMakeLists.txt文件 包含的内容

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么选择伪原创工具?伪原创工具推荐

什么是伪原创工具&#xff1f;伪原创工具是一种可以将已有文本进行修改、改写或重新组合&#xff0c;生成新的文本内容的工具。 伪原创工具的作用 节省时间和精力&#xff1a;手工创作内容需要耗费大量时间和精力&#xff0c;而伪原创工具可以在短时间内生成大量内容&#xf…

嵌入式中如何用C语言操作sqlite3(07)

sqlite3编程接口非常多&#xff0c;对于初学者来说&#xff0c;我们暂时只需要掌握常用的几个函数&#xff0c;其他函数自然就知道如何使用了。 数据库 本篇假设数据库为my.db,有数据表student。 nonamescore4嵌入式开发爱好者89.0 创建表格语句如下&#xff1a; CREATE T…

C++中实现雪花算法来在秒级以及毫秒及时间内生成唯一id

1、雪花算法原理 雪花算法&#xff08;Snowflake Algorithm&#xff09;是一种用于生成唯一ID的算法&#xff0c;通常用于分布式系统中&#xff0c;以确保生成的ID在整个分布式系统中具有唯一性。它的名称来源于雪花的形状&#xff0c;因为生成的ID通常是64位的整数&#xff0…

【数据结构】哈希表(详)

文章目录 前言正文一、基本概念二、基本原理1.哈希函数1.1直接定址法&#xff08;常用&#xff09;1.2除留余数法&#xff08;常用&#xff09;1.3 平方取中法&#xff08;了解&#xff09;1.4 折叠法(了解)1.5 随机数法(了解)1.6数学分析法(了解) 2.哈希冲突2.1 平均查找长度2…

QT配置MySQL数据库 ninja: build stopped: subcommand failed

QT配置MySQL数据库 我当前的软件版本&#xff1a;QT Creator 10.0.2 (community)&#xff0c;MingW 6.4.3 (QT6)&#xff0c;MySQL 8.0。 MySQL不配置支持的数据库有QList("QSQLITE", "QODBC", "QPSQL")&#xff0c;这个时候是不支持MYSQL数据…

No127.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

箱讯科技成功闯入第八届“创客中国”全国总决赛—在国际物流领域一枝独秀

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 2023年9月26日&#xff0c;第八届“创客中国”数字化转型中小企业创新创业大赛决赛在贵州圆满收官。 经过初赛、复赛、决赛的激烈角逐&#xff0c;箱讯科技与众多强劲对手同台竞技&#xff0c;最终凭借出…

Android gradle dependency tree change(依赖树变化)监控实现

文章目录 前言基本原理执行流程diff 报告不同分支 merge 过来的 diff 报告同个分支产生的 merge 报告同个分支提交的 diff 报告 具体实现原理我们需要监控怎样的 Dendenpency 变化怎样获取 dependency Treeproject.configurations 方式./gradlew dependenciesAsciiDependencyRe…

铁路用热轧钢轨

声明 本文是学习GB-T 2585-2021 铁路用热轧钢轨. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了铁路用钢轨的订货内容、分类、尺寸、外形、质量及允许偏差、技术要求、试验方法、检 验规则、标志及质量证明书。 本标准适用于3…

iMovie for Mac v10.3.9(视频剪辑)

iMovie是一款视频剪辑软件&#xff0c;广泛应用于Mac和iOS设备。以下是关于iMovie软件的一些推荐信息&#xff1a; 简单易用。iMovie的设计简洁&#xff0c;操作简单&#xff0c;即使是没有剪辑经验的新手也可以轻松上手。软件内置了丰富的视觉效果、滤镜、绿幕抠图、分屏和画…

【腾讯云国际站】CDN内容分发网络特性介绍

为什么使用腾讯云国际站 CDN 内容分发网络&#xff1f; 当用户直接访问源站中的静态内容时&#xff0c;可能面临的体验问题&#xff1a; 客户离服务器越远&#xff0c;访问速度越慢。客户数量越多&#xff0c;网络带宽费用越高。跨境用户访问体验较差。 腾讯云国际站CDN 如何改…

Ctfshow web入门 XSS篇 web316-web333 详细题解 全

CTFshow XSS web316 是反射型 XSS 法一&#xff1a; 利用现成平台 法二&#xff1a; 自己搭服务器 先在服务器上面放一个接受Cookie的文件。 文件内容&#xff1a; <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt"…

MySQL学习笔记19

MySQL日志文件&#xff1a;MySQL中我们需要了解哪些日志&#xff1f; 常见日志文件&#xff1a; 我们需要掌握错误日志、二进制日志、中继日志、慢查询日志。 错误日志&#xff1a; 作用&#xff1a;存放数据库的启动、停止和运行时的错误信息。 场景&#xff1a;用于数据库的…

dataGrip导出导入的方式

导出&#xff1a;选中需要导出的表 导入&#xff1a;选中导出的sql文件

【操作系统笔记一】程序运行机制CPU指令集

内存地址 指针 / 引用 指针、引用本质上就是内存地址&#xff0c;有了内存地址就可以操作对应的内存数据了。 不同的数据类型 字节序 大端序&#xff08;Big Endian&#xff09;&#xff1a;字节顺序从低地址到高地址顺序存储的字节序小端序&#xff08;Little Endian&#…

无需公网IP,实现公网SSH远程登录MacOS【内网穿透】

目录 前言 1. macOS打开远程登录 2. 局域网内测试ssh远程 3. 公网ssh远程连接macOS 3.1 macOS安装配置cpolar 3.2 获取ssh隧道公网地址 3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址 4.1 保留一个固定TCP端口地址 4.2 配置固定TCP端口地址 5. 使用固定TCP端…

云可观测性:提升云环境中应用程序可靠性

随着云计算的兴起和广泛应用&#xff0c;越来越多的企业将其应用程序和服务迁移到云环境中。在这个高度动态的环境中&#xff0c;确保应用程序的可靠性和可管理性成为了一个迫切的需求。云可观测性作为一种解决方案&#xff0c;针对这一需求提供了有效的方法和工具。本文将介绍…

windows 安装 MySQL 绿色版

windows 安装 MySQL 绿色版 下载 官网&#xff1a; MySQL下载页面&#xff1a; MySQL直接下载链接&#xff1a;https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.34-winx64.zip 安装 将下载的mysql.zip文件解压缩到指定目录 搜索 cmd 并以管理员身份运行 切换到…

自制网页。

文章目录 注:代码中图片等素材均来自网络,侵删 20230920_213831 index.html <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-…

成为黄金代理,必须考虑到这一点

目前很多投资者都会选择黄金代理进行现货黄金投资账户的开立。一方面是市场中各种各样的现货黄金代理&#xff0c;越来越专业&#xff0c;提供的交易服务越来越好&#xff0c;另一方面是黄金代理和黄金平台进行合作&#xff0c;如果平台选得好&#xff0c;投资者在平台开户还是…