T265 記録された rosbag アンパッキング: IMU シーケンスと画像シーケンスのアンパッキング方法、および双眼ユーロック、双眼タム データ セットの作成方法

目次

1. レコードバッグパッケージ

2. 左右の画像の分解

3. IMUデータを削除する

4.eruoc および tum データセットの作成方法

4.1 eruoc データセット形式

4.2 タイムスタンプの調整

4.3 imu.csv ファイルの書き込み

4.4 インデックスファイルの生成

4. スクリプトによって解凍が完了します。


1. レコードバッグパッケージ

        ここでは私のクラスメートのブログをお勧めします。T265 ros パッケージを記録し、いくつかの問題を解決するには、このブログを参照してください。

RealSense T265 を使用してバッグを記録するhttps://blog.csdn.net/weixin_44760904/article/details/130512863?spm=1001.2014.3001.5501

2. 左右の画像の分解

        ここでは、まず録音パッケージの情報を確認し、次のコマンドを使用してパッケージ名を確認します。

rosbag info <包名>

        次の 3 つの情報が見つかりました。

        /fisheye1: 左目の画像に対応します

        /fisheye2: 右の画像に対応します

        /imu: imuに対応する情報

        次のスクリプトを使用して、左右の画像を分割します。

import roslib
import rosbag
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError
 
path='/home/xxxx/Desktop/left/' 
class ImageCreator():
 
 
    def __init__(self):
        self.bridge = CvBridge()
        with rosbag.Bag('/home/xxxx/Desktop/out.bag', 'r') as bag:   
            for topic,msg,t in bag.read_messages():
                if topic == "/fisheye1": 
                        try:
                            cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")
                        except CvBridgeError as e:
                            print e
                        timestr = "%.6f" %  msg.header.stamp.to_sec()

                        image_name = timestr+ ".jpg" 
                        cv2.imwrite(path+image_name, cv_image) 

 
 
if __name__ == '__main__':
    try:
        image_creator = ImageCreator()
    except rospy.ROSInterruptException:
        pass

        ここで、 path は画像を保存するパス、 topic は画像に対応するカメラトピック (/fisheye1、/fisheye2) です。%.6f は、小数点以下の桁数を保持するためのものですが、状況に応じて異なります。

        スクリプトを実行して、左と右の画像を取得します。

3. IMUデータを削除する

        IMU データは、タイムスタンプ、3 つの加速度情報、3 つの角速度情報に分割されます。

        次のスクリプトを実行することで、それを分離して csv ファイルを形成できます。

import rosbag
import csv
from sensor_msgs.msg import Imu


bag = rosbag.Bag('/home/xxxx/Desktop/out.bag')


csvfile = open('imu.csv', 'w')
csvwriter = csv.writer(csvfile)


csvwriter.writerow(['timestamp', 'ax', 'ay', 'az', 'wx', 'wy', 'wz'])


for topic, msg, t in bag.read_messages(topics=['/imu']):

    timestamp = msg.header.stamp.to_nsec()
    ax = msg.linear_acceleration.x
    ay = msg.linear_acceleration.y
    az = msg.linear_acceleration.z
    wx = msg.angular_velocity.x
    wy = msg.angular_velocity.y
    wz = msg.angular_velocity.z
    csvwriter.writerow([timestamp, ax, ay, az, wx, wy, wz])

bag.close()
csvfile.close()

        スクリプトを実行すると、次の csv ファイルが得られました。

4.eruoc および tum データセットの作成方法

4.1 eruoc データセット形式

        写真形式:

        まず、左右の画像のタイムスタンプを揃えます。どちらも19ビットです。

        その中には、タイムスタンプと画像の関係を保存するファイル data.csv がありますが、これらは実際には同じです。

        これはIMUのデータです。

4.2 タイムスタンプの調整

        記録されたパケットのタイムスタンプが揃っていないことがわかり、それらを揃える必要があります。

        位置合わせの原理: 主に左目画像に両眼画像を使用するため、右目画像を左目画像のタイムスタンプと位置合わせすることで、画像の損失率を最小限に抑えることができます。 IMU。

import os
import os
import shutil

folder1_path = "/home/liuhongwei/Desktop/left"
folder2_path = "/home/liuhongwei/Desktop/right"

output_folder_path = "/home/liuhongwei/Desktop/righti"



folder1_files = sorted(os.listdir(folder1_path))


folder2_files = sorted(os.listdir(folder2_path))


if len(folder1_files) != len(folder2_files):
    print("no")
else:

    for i in range(len(folder2_files)):
        source_path = os.path.join(folder2_path, folder2_files[i])
        target_path = os.path.join(output_folder_path, folder1_files[i])
        shutil.copyfile(source_path, target_path)

    print("yes")

        スクリプトを実行した後、位置が調整されたことがわかりました: (注意: 両眼画像が異なる場合があります。このスクリプトを実行する前に、右目の画像を削除するか、左目の画像で埋める必要があります)

4.3 imu.csv ファイルの書き込み

import rosbag
import csv
from sensor_msgs.msg import Imu


bag = rosbag.Bag('bag包的地址')


csvfile = open('imu1.csv', 'w')
csvwriter = csv.writer(csvfile)


csvwriter.writerow(['timestamp [ns]', 'w_RS_S_x [rad s^-1]', 'w_RS_S_y [rad s^-1]', 'w_RS_S_z [rad s^-1]', 'a_RS_S_x [rad m s^-2]', 'a_RS_S_y [rad m s^-2]', 'a_RS_S_z [rad m s^-2]'])


for topic, msg, t in bag.read_messages(topics=['/imu']):

    timestamp = msg.header.stamp.to_nsec()
    ax = msg.linear_acceleration.x
    ay = msg.linear_acceleration.y
    az = msg.linear_acceleration.z
    wx = msg.angular_velocity.x
    wy = msg.angular_velocity.y
    wz = msg.angular_velocity.z
    csvwriter.writerow([timestamp, wx, wy, wz, ax, ay, az])

bag.close()
csvfile.close()

        スクリプトを実行すると、csv ファイルが生成されました。それをチェックしよう:

        これまでに、IMU ファイルも生成されました。

        tum データセットでは、txt 形式に変換する必要があります。次のスクリプトを実行して、csv で保存された IMU 情報を txt 形式に変換します。

import csv

def csv_to_txt(csv_file, txt_file):
    with open(csv_file, 'r') as file:
        reader = csv.reader(file)
        with open(txt_file, 'w') as output_file:
            writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            for row in reader:
                writer.writerow(row)

csv_file = 'csv文件的地址'
txt_file = '转换保存的txt文件地址'
csv_to_txt(csv_file, txt_file)

        スクリプトを実行すると、IMU 情報を保存する csv ファイルが txt ファイル形式 (TUM データセット形式) で保存されていることがわかります。

4.4 インデックスファイルの生成

        次のスクリプト ファイルを使用して、画像のインデックス ファイルを生成します。

import os
import csv

def create_image_csv(folder_path, csv_file_path):
    with open(csv_file_path, 'wb') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['TimeStamp', 'Image Name'])

        for filename in os.listdir(folder_path):
            if filename.endswith('.jpg') or filename.endswith('.png'):
                image_name = os.path.splitext(filename)[0]
                writer.writerow([image_name, filename])

folder_path = '/home/liuhongwei/Desktop/right'  
csv_file_path = '/home/liuhongwei/Desktop/right.csv'  

create_image_csv(folder_path, csv_file_path)

        図に示すように、生成が完了すると、左右の項目とそのインデックス ファイルに対応するタイムスタンプが次のようになります。

        この時点で、ファイルが生成されます。実行した内容を euroc データセットの形式にパッケージ化できます。

        TUM データセットの場合、画像のタイムスタンプ ファイルを生成する必要があります。次のスクリプトを使用して、画像シーケンスと対応するタイムスタンプ ファイルを生成します。

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

path = '要保存的图像序列地址'
txt_file = '时间戳文件的地址(自动创建)'  # Path to the text file

class ImageCreator():
    def __init__(self):
        self.bridge = CvBridge()
        image_names = []  # List to store image names

        with rosbag.Bag('录制的bag包地址', 'r') as bag:
            for topic, msg, t in bag.read_messages():
                if topic == "/fisheye1":
                    try:
                        cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
                    except CvBridgeError as e:
                        print(e)
                        continue

                    timestr = "%.9f" % msg.header.stamp.to_sec()
                    image_name = timestr.replace('.', '')  # Remove periods from the timestamp
                    cv2.imwrite(path + image_name + '.png', cv_image)  # Save as PNG format
                    image_names.append(image_name)  # Add image name to the list

        # Save image names to the text file
        with open(txt_file, 'w') as f:
            f.write('\n'.join(image_names))

if __name__ == '__main__':
    try:
        image_creator = ImageCreator()
    except rospy.ROSInterruptException:
        pass

        tum データセットに必要なタイムスタンプ情報が生成されたことがわかります。

4. スクリプトによって解凍が完了します。

        以下のスクリプトを実行すると、左右の画像を自動で分解し、IMUのcsv情報とtxt情報を自動生成し、タイムスタンプを合わせて、左画像のタイムスタンプを生成します。

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

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

def CreateDIR():
    folder_name = 'bag_tum'
    subfolders = ['left', 'righti']

    if not os.path.exists(folder_name):
        os.makedirs(folder_name)

    # 在主文件夹下创建子文件夹
    for subfolder in subfolders:
        subfolder_path = os.path.join(folder_name, subfolder)
        if not os.path.exists(subfolder_path):
            os.makedirs(subfolder_path)


def CreateIMUCSV(umpackbag):
    csvfile = open('imudata.csv', 'w')
    csvwriter = csv.writer(csvfile)
    csvwriter.writerow(['timestamp [ns]', 'w_RS_S_x [rad s^-1]', 'w_RS_S_y [rad s^-1]', 'w_RS_S_z [rad s^-1]', 'a_RS_S_x [rad m s^-2]', 'a_RS_S_y [rad m s^-2]', 'a_RS_S_z [rad m s^-2]'])
    for topic, msg, t in umpackbag.read_messages(topics=['/imu']):
        timestamp = msg.header.stamp.to_nsec()
        ax = msg.linear_acceleration.x
        ay = msg.linear_acceleration.y
        az = msg.linear_acceleration.z
        wx = msg.angular_velocity.x
        wy = msg.angular_velocity.y
        wz = msg.angular_velocity.z
        csvwriter.writerow([timestamp, wx, wy, wz, ax, ay, az])
    #umpackbag.close()
    csvfile.close()

def TransIMUdatatotxt():
    csv_file = './imudata.csv'
    txt_file = './imudata.txt'
    with open(csv_file, 'r') as file:
        reader = csv.reader(file)
        with open(txt_file, 'w') as output_file:
            writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            for i, row in enumerate(reader):
                if i == 0:
                    writer.writerow(['#' + cell for cell in row])  # 添加#号
                else:
                    writer.writerow(row)

def SaveImageFishereyeleft(umpackbag):
    path = './bag_tum//left/'
    txt_file = './timestamp.txt'
    bridge = CvBridge()
    image_names = []

    with rosbag.Bag(bagname, 'r') as bag:
        for topic, msg, t in umpackbag.read_messages():
            if topic == "/fisheye1":
                try:
                    cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
                except CvBridgeError as e:
                    print(e)
                    continue

                timestr = "%.9f" % msg.header.stamp.to_sec()
                image_name = timestr.replace('.', '')  # Remove periods from the timestamp
                cv2.imwrite(path + image_name + '.png', cv_image)  # Save as PNG format
                image_names.append(image_name)  # Add image name to the list
    with open(txt_file, 'w') as f:
        f.write('\n'.join(image_names))

def SaveImageFishereyeright(umpackbag):
    path = './bag_tum//righti/'
    bridge = CvBridge()
    image_names = []

    with rosbag.Bag(bagname, 'r') as bag:
        for topic, msg, t in umpackbag.read_messages():
            if topic == "/fisheye2":
                try:
                    cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
                except CvBridgeError as e:
                    print(e)
                    continue

                timestr = "%.9f" % msg.header.stamp.to_sec()
                image_name = timestr.replace('.', '')  # Remove periods from the timestamp
                cv2.imwrite(path + image_name + '.png', cv_image)  # Save as PNG format
                image_names.append(image_name)  # Add image name to the list

def dealwithTimeStamp():
    folder1_path = './bag_tum//left/'
    folder2_path = './bag_tum//right/'
    output_folder_path = './bag_tum//righti/'
    folder1_files = sorted(os.listdir(folder1_path))
    folder2_files = sorted(os.listdir(folder2_path))
    if len(folder1_files) != len(folder2_files):
        print("录制包时左右目图像数量不一致,请手动处理")
    else:
        for i in range(len(folder2_files)):
            source_path = os.path.join(folder2_path, folder2_files[i])
            target_path = os.path.join(output_folder_path, folder1_files[i])
            shutil.copyfile(source_path, target_path)
        print("图像序列生成完毕")
    if os.path.exists(folder2_path):
        shutil.rmtree(folder2_path)


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    bagname = './road.bag'
    umpackbag = rosbag.Bag(bagname)
    CreateDIR()
    CreateIMUCSV(umpackbag)
    TransIMUdatatotxt()
    SaveImageFishereyeleft(umpackbag)
    SaveImageFishereyeright(umpackbag)
    dealwithTimeStamp()

        以下のスクリプトを実行すると、TUMデータセットとEUROCデータセットに必要なファイル情報がスクリプトの同名フォルダ配下に生成されます。

おすすめ

転載: blog.csdn.net/qq_41694024/article/details/130598248