Loading

rosbag 包提取图片和点云数据

环境

  • Ubuntu 20.04
  • ROS noetic
  • Python 3.8.10

⚠️ 注意:Python 版本很重要,建议用 3.8.10 版本,如果使用更新的版本,会导致程序需要的库版本不对应,会报错。建议使用 conda 创建一个虚拟环境最佳,创建指令:conda create -n ros_env python=3.8.10

安装所需的包

在创建的 Python 3.8.10 的环境里安装如下所需的包:

pip install rospkg gnupg pycryptodomex opencv-python tqdm

查看 bag 包参数

运行 rosbag info xxx.bag (xxx 为你 bag 的文件名)查看你需要提取的 bag 包里的话题 topic,记下来然后在下面的代码里进行更改。

提取代码

需要更改 main 函数里的 bagfile_pathcamera_topicpointcloud_topicoutput_path 参数。程序运行完成后即可在你所设定的 output_path 路径里找到提取的文件。

import os
import cv2
import rosbag
from tqdm import tqdm
from cv_bridge import CvBridge


class ExtractBagData(object):
    def __init__(self, bagfile_path, camera_topic, pointcloud_topic, output_path):
        self.bagfile_path = bagfile_path  # bag 路径
        self.camera_topic = camera_topic  # 相机话题 topic
        self.pointcloud_topic = pointcloud_topic  # 点云话题 topic
        self.output_path = output_path  # 输出的根路径
        self.image_dir = os.path.join(output_path, "images")  # 存放照片的路径
        self.pointcloud_dir = os.path.join(output_path, "pointcloud")  # 存放点云的路径

        # 检查路径是否存在,否则创建提取图片和点云的目录 ./output_path/images  ./output_path/pointcloud
        if not os.path.exists(self.image_dir):
            os.makedirs(self.image_dir)
        if not os.path.exists(self.pointcloud_dir):
            os.makedirs(self.pointcloud_dir)

    def bag_to_image(self):
        """ 提取图片
        """
        bag = rosbag.Bag(self.bagfile_path, "r")  # 读取 bag
        bridge = CvBridge()  # 用于将图像消息转为图片
        bag_data_imgs = bag.read_messages(self.camera_topic)  # 读取图像消息

        pbar = tqdm(bag_data_imgs)
        for index, [topic, msg, t] in enumerate(pbar, start=0):
            pbar.set_description("extract image id: %s" % (index + 1))
            # 消息转为图片
            cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
            # 存储图片 .bmp .png .jpg
            cv2.imwrite(os.path.join(self.image_dir, str(index) + ".png"), cv_image)
            # index += 1

    def bag_to_pointcloud(self):
        """ 提取点云
        - 提取点云数据为 pcd 后缀文件,默认提取以时间戳命名
        - 提取命令:rosrun pcl_ros bag_to_pcd result.bag /velodyne_points ./pointcloud
        """
        cmd = "rosrun pcl_ros bag_to_pcd %s %s %s" % (
            self.bagfile_path,
            self.pointcloud_topic,
            self.pointcloud_dir,
        )
        os.system(cmd)

        # 读取提取的 pcd 点云数据,把文件名修改为按照顺序索引名
        pcd_files_list = os.listdir(self.pointcloud_dir)
        # 因为提取的 pcd 是以时间戳命名的,但是存放到列表中并不是按照时间戳从小到大排列,这里对时间戳进行重新排序
        pcd_files_list_sorted = sorted(pcd_files_list, reverse=False)

        pbar = tqdm(pcd_files_list_sorted)
        for index, pcd_file in enumerate(pbar, start=0):
            pbar.set_description("extract poindcloud id: %s" % (index + 1))
            os.rename(
                os.path.join(self.pointcloud_dir, pcd_file),
                os.path.join(self.pointcloud_dir, str(index) + ".pcd"),
            )
            print("pcd_file name: ", pcd_file)


if __name__ == "__main__":
    extract_bag = ExtractBagData(
        bagfile_path="/mnt/e/2024-01-13-12-40-28.bag",  # bag 文件的绝对路径
        camera_topic="/stereo_publisher/color/image",  # 相机 topic
        pointcloud_topic="/livox/lidar",  # 点云 topic
        output_path="/mnt/e/output/",  # 输出的根路径
    )

    extract_bag.bag_to_image()  # 提取图片
    extract_bag.bag_to_pointcloud()  # 提取点云

附:.bag 转 .txt

如果 bag 中获取的是数据包,可以直接使用下面的语句进行格式转换:

rostopic echo -b <bag_name>.bag -p /<topic_name> > <new_name>.txt
# 举例
rostopic echo -b data.bag -p /cmd_vel > output.txt
posted @ 2024-01-19 14:21  滑稽果  阅读(367)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end