使用D435i相机录制TUM格式的数据集

这篇具有很好参考价值的文章主要介绍了使用D435i相机录制TUM格式的数据集。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本文写于2023年3月14日。D435i相机的rgb图像与depth图像的像素没有对齐,在此记录一下如何像素对齐

系统版本

Ubuntu18.04 + ROS melodic

一、使用realsense SDK录制bag包的情况

1.录制视频

这一步需要使用InterRealSenseD435i SDK2,可以参考此链接安装。
打开Intel RealSense Viewer。设置Depth Stream以及Color Stream的图像分辨率为640 × 480,设置采集帧率为30 fps。点击左上角的Record按钮即可进行录制,开始录制后,点击左上角的Stop按钮即可结束录制并保存录制结果。

若点击Record按钮后出现以下报错,则更改一下保存路径。

UNKNOWN in rs2_create_record_device_ex(device:0x7f151c000b20, file:/):
Error opening file: /home/d/Documents/20220723_223742.bag

使用D435i相机录制TUM格式的数据集
点击右上角的齿轮图标,选择Settings,然后改变存储路径,之后点击ApplyOK

结束录制后,在相应存储路径下即生成.bag文件。
使用D435i相机录制TUM格式的数据集

2.、提取rgb和depth图片

1.

首先,进入bag文件的存储路径并打开终端,通过rosbag info 20220723_202328.bag查看待提取的深度图及彩色图所对应的 topic,如下图所示:
使用D435i相机录制TUM格式的数据集
使用D435i相机录制TUM格式的数据集
新建文件夹room(此名称随意),在此文件夹下新建文件夹rgbdepth保存提取出来的深度图和彩色图,同时新建文件rgb.txtdepth.txt为对齐时间戳做准备。

2.

执行以下python脚本对齐并提取图像.py
:我保存的路径出现了中文,所以在第一行加入了# -*- coding: utf-8 -*-,否则会报错SyntaxError: Non-ASCII character '\xe8' in file 参考链接

这部分在原有的提取图片的基础上添加了像素对齐的功能
参考链接:
Realsense相机在linux下的配置使用,RGB与depth图像对齐(此博客有对齐图像与非对齐图像的比较)
realsense深度图像读取对齐与保存(下面程序的框架来源)
realsense bag文件时间戳获取(下面程序时间戳获取来源)

#coding=utf-8
import pyrealsense2 as rs
import numpy as np
import cv2
import time
import os
#像素对齐了
pipeline = rs.pipeline()

#Create a config并配置要流​​式传输的管道
config = rs.config()
config.enable_device_from_file("/home/d/下载/20221128_161053.bag")#这是打开相机API录制的视频
# config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
# config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

profile = pipeline.start(config)

depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print("Depth Scale is: " , depth_scale)

align_to = rs.stream.color
align = rs.align(align_to)

# 保存路径
save_path = '/home/d/文档/数据集/自己录的D435i/table/'

# 保存的图片和实时的图片界面
# cv2.namedWindow("live", cv2.WINDOW_AUTOSIZE)
# cv2.namedWindow("save", cv2.WINDOW_AUTOSIZE)
number = 0

file_handle1 = open('/home/d/文档/数据集/自己录的D435i/table/rgb.txt', 'w')
file_handle2 = open('/home/d/文档/数据集/自己录的D435i/table/depth.txt', 'w')

# 主循环
try:
    while True:
        #获得深度图的时间戳
        frames = pipeline.wait_for_frames()
        number = number + 1
        depth_timestamp = "%.6f" % (frames.timestamp / 1000)
        rgb_timestamp = "%.6f" % (frames.timestamp / 1000 + 0.000017)#对比了 提取图片.py 的时间戳,发现rgb比depth多0.000017

        aligned_frames = align.process(frames)
        #获取对齐后的深度图与彩色图
        aligned_depth_frame = aligned_frames.get_depth_frame()
        color_frame = aligned_frames.get_color_frame()

        if not aligned_depth_frame or not color_frame:
            continue
        
        depth_data = np.asanyarray(aligned_depth_frame.get_data(), dtype="float16")
        depth_image = np.asanyarray(aligned_depth_frame.get_data())
        color_image = np.asanyarray(color_frame.get_data())
        color_image = cv2.cvtColor(color_image,cv2.COLOR_BGR2RGB)
        depth_mapped_image = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.05), cv2.COLORMAP_JET)
        
        #下面两行是opencv显示部分
        # cv2.imshow("live", np.hstack((color_image, depth_mapped_image)))
        # key = cv2.waitKey(30)

        rgb_image_name = rgb_timestamp+ ".png"
        depth_image_name = depth_timestamp+ ".png"
        rgb_path = "rgb/" + rgb_image_name
        depth_path = "depth/" + depth_image_name
        # rgb图片路径及图片保存为png格式
        file_handle1.write(rgb_timestamp + " " + rgb_path + '\n')
        cv2.imwrite(save_path + rgb_path, color_image)
        # depth图片路径及图片保存为png格式
        file_handle2.write(depth_timestamp + " " + depth_path + '\n')
        cv2.imwrite(save_path + depth_path, depth_image)
        print(number, rgb_timestamp, depth_timestamp)
        #cv2.imshow("save", np.hstack((saved_color_image, saved_depth_mapped_image)))

        #查看话题包有多少帧图片,下面就改成多少
        if number == 2890:
            cv2.destroyAllWindows()
            break    
finally:
    pipeline.stop()

file_handle1.close()
file_handle2.close()

需要将以下几行路径改成自己对应的路径

config.enable_device_from_file("/home/d/下载/20221128_161053.bag")

save_path = '/home/d/文档/数据集/自己录的D435i/table/'

file_handle1 = open('/home/d/文档/数据集/自己录的D435i/table/rgb.txt', 'w')
file_handle2 = open('/home/d/文档/数据集/自己录的D435i/table/depth.txt', 'w')

还有判断停止的条件

#查看话题包有多少帧图片,下面就改成多少
if number == 2890:

改好了之后打开终端输入以下指令执行python脚本

python 对齐并提取图像.py

3.对齐时间戳

由于深度图及彩色图的时间戳并非严格一一对齐,存在一定的时间差,因此需将深度图及彩色图按照时间戳最接近原则进行两两配对。将associate.py脚本文件存储至room文件夹下,如图所示:
使用D435i相机录制TUM格式的数据集

associate.py脚本文件:

"""
The RealSense 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 numpy


def 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 name

    Output:
    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) tuples
    second_list -- second dictionary of (stamp,data) tuples
    offset -- time offset between both dictionaries (e.g., to model the delay between the sensors)
    max_difference -- search radius for candidate generation

    Output:
    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 matches


if __name__ == '__main__':

    # parse command line
    parser = 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.txt

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

至此,数据集制作完成。

二、用realsense-ros打开相机录制bag包

1.将深度图对齐到RGB

打开realsense-ros/realsense2_camera/launch/rs_d435_camera_with_model.launch文件,将align_depth的值改为true
使用D435i相机录制TUM格式的数据集

2.使用realsense-ros打开相机

切换到安装realsense-ros的工作空间

source devel/setup.bash
roslaunch realsense2_camera rs_d435_camera_with_model.launch

之后新建终端查看rostopic list/camera/aligned_depth_to_color/image_raw就是对齐后的深度图像话题
使用D435i相机录制TUM格式的数据集

3.录制rosbag

参考链接:如何优雅的录制ROS的rosbag包?

1.直接使用命令

rosbag record -O xxx.bag topic-name

根据上面的格式,我把路径补全,并且选择监听的话题,因此我使用下面的命令

rosbag record -O /home/d/1.bag /camera/color/image_raw /camera/aligned_depth_to_color/image_raw

录制结束按Ctrl+C暂停

2.写一个launch文件

<launch>
	<node pkg="rosbag" type="record" name="bag_record" args="topic-name1 topic-name1 -O xxxx"/>                                                                                                
</launch>

根据上面的格式,我把路径补全,并且选择监听的话题,因此我launch文件改成下面的

<launch>
	<node pkg="rosbag" type="record" name="bag_record" args="/camera/color/image_raw /camera/aligned_depth_to_color/image_raw -O /home/d/1"/>                                                                                                            
</launch>

我把上面的文件命名为rosbag_record.launch,并且放在/home/d/catkin_ws/src/realsense-ros/realsense2_camera/launch/路径下
切换到安装realsense-ros的工作空间

source devel/setup.bash
roslaunch realsense2_camera rosbag_record.launch

录制结束按Ctrl+C暂停

4.提取图像以及对齐时间戳

新建文件夹room(此名称随意),在此文件夹下新建文件夹rgbdepth保存提取出来的深度图和彩色图,同时新建文件rgb.txtdepth.txt为对齐时间戳做准备
执行以下python脚本提取图像.py

注意:该脚本只能提取图像,并不能对齐像素(因为第二部分的第1步已经对齐过了)

# -*- coding: utf-8 -*-

import roslib
import rosbag
import rospy
import cv2
import os
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError

rgb = '/home/d/视频/room/rgb/'  #rgb path
depth = '/home/d/视频/room/depth/'   #depth path
bridge = CvBridge()

file_handle1 = open('/home/d/视频/room/depth.txt', 'w')
file_handle2 = open('/home/d/视频/room/rgb.txt', 'w')

with rosbag.Bag('/home/d/视频/20220723_202328.bag', 'r') as bag:
    for topic,msg,t in bag.read_messages():
        if topic == "/camera/aligned_depth_to_color/image_raw":  #depth topic
            cv_image = bridge.imgmsg_to_cv2(msg)
            timestr = "%.6f" %  msg.header.stamp.to_sec()   #depth time stamp
            image_name = timestr+ ".png"
            path = "depth/" + image_name
            file_handle1.write(timestr + " " + path + '\n')
            cv2.imwrite(depth + image_name, cv_image)
        if topic == "/camera/color/image_raw":   #rgb topic
            cv_image = bridge.imgmsg_to_cv2(msg,"bgr8")
            timestr = "%.6f" %  msg.header.stamp.to_sec()   #rgb time stamp
            image_name = timestr+ ".png"
            path = "rgb/" + image_name
            file_handle2.write(timestr + " " + path + '\n')
            cv2.imwrite(rgb + image_name, cv_image)
file_handle1.close()
file_handle2.close()

需要将以下几行路径改成自己对应的路径

rgb = '/home/d/视频/room/rgb/'  #rgb path
depth = '/home/d/视频/room/depth/'   #depth path
bridge = CvBridge()

file_handle1 = open('/home/d/视频/room/depth.txt', 'w')
file_handle2 = open('/home/d/视频/room/rgb.txt', 'w')

with rosbag.Bag('/home/d/视频/20220723_202328.bag', 'r') as bag:

改好了之后打开终端输入以下指令执行python脚本

python 提取图像.py

提取完了之后按照上面相同的方式对齐时间戳即可文章来源地址https://www.toymoban.com/news/detail-484846.html

到了这里,关于使用D435i相机录制TUM格式的数据集的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • intel realsense d435i相机标定中文文档

    此文档参考了官方的英文文档,原地址面向英特尔®实感™深度摄像头的 IMU 校准工具 (intelrealsense.com) IMU概述:惯性测量单元(imu)通常由加速度计组成,加速度通常以国际系统(SI)的米/秒为单位输出平方(m/s^2)和陀螺仪,陀螺仪通常以SI单位测量角速度弧度/秒(rad/s)。英特尔Real

    2024年02月09日
    浏览(33)
  • python实现d435i深度相机测量两点之间的距离

    本文介绍python方法实现intel公司realsense系列d435i深度相机测量彩色图像上两点之间的距离。 原理很简单,就是将相机获得的彩色图像流与深度流对齐,这样彩色图像上的每个像素就会对应一个深度值,作为z坐标,然后通过相机内参获得该像素的x坐标和y坐标。我们获得的x、

    2024年02月16日
    浏览(26)
  • 【D435i深度相机YOLO V5结合实现目标检测】

    参考:Ubutntu下使用realsense d435i(三):使用yolo v5测量目标物中心点三维坐标 欢迎大家阅读2345VOR的博客【D435i深度相机YOLO V5结合实现目标检测】🥳🥳🥳 2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空🛹🛹🛹 本文章属于

    2024年02月08日
    浏览(44)
  • Ubuntu18.04安装配置使用Intel RealSense D435i深度相机以及在ROS环境下配置

    最近因为学习开发需要,要开始接触一些视觉相关的内容,拿到了一个Inter 的D435i深度相机,记录一下在Ubuntu18环境下配置SDK 包的历程 注意 : Intel官方最新版的librealsense版本与ROS1的ROS Wrapper是 版本不一致的 ,且ROS Wrapper支持的是较低版本的SDK ,具体可以去网站查看 如果完全

    2024年02月07日
    浏览(37)
  • Ubuntu 20.04 Intel RealSense D435i 相机标定教程

    报错:sumpixel_test.cpp:2:10: fatal error: backward.hpp: 没有那个文件或目录,将sumpixel_test.cpp中# include \\\"backward.hpp\\\"改为:#include “code_utils/backward.hpp”。 报错 创建rs_imu_calibration.launch 找到realsense-ros包,进入/catkin_ws/src/realsense2_camera/launch(路径仅供参考),复制其中的rs_camera.launch,并重

    2024年01月16日
    浏览(32)
  • jetsonTX2 nx配置yolov5和D435I相机,完整步骤

    转载一篇问题解决博客:问题解决 一、烧录系统 使用SDK烧录 二、安装archiconda3 JETSON TX2 NX的架构是aarch64,与win10,linxu不同,所以不能安装Anaconda,这里安装对应的archiconda。 1. 安装 2. 配置环境变量 3. 创建虚拟环境 其他相关命令(来源:相关命令) 换源 安装成功截图 三、安装

    2024年02月03日
    浏览(34)
  • Ubuntu 18.04安装D435i 相机驱动及Ros1 Wrapper

    1.安装前注意 librealsense SDK相当于相机的驱动,SR300和ZR300的支持驱动是librealsense SDK 1.0,而D435i是librealsense SDK 2.0 **安装前一定要注意librealsense,realsense-ros(即Ros Wrapper),D435i相机固件版本三者之间的版本对应关系。**ros1环境只支持librealsense2.50.0之前的版本,ros2环境要下载librealse

    2024年02月22日
    浏览(36)
  • 项目设计:YOLOv5目标检测+机构光相机(intel d455和d435i)测距

    1.1  Intel D455 Intel D455 是一款基于结构光(Structured Light)技术的深度相机。 与ToF相机不同,结构光相机使用另一种方法来获取物体的深度信息。它通过投射可视光谱中的红外结构光图案,然后从被拍摄物体表面反射回来的图案重建出其三维形状和深度信息。 Intel D455 深度相机

    2024年02月08日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包