使用 Python 从 ROS Bag 中提取图像:详解与实现

news2024/12/19 1:46:16

在机器人应用中,ROS (Robot Operating System) 是一个常见的框架。ROS Bag(rosbag)是 ROS 中用于记录和回放数据流(例如传感器数据、话题消息等)的一种强大工具。有时,我们需要将存储在 rosbag 文件中的图像数据提取并保存为图像文件以便进一步分析或处理。本文将介绍如何编写一个 Python 脚本,从 rosbag 文件中提取图像并保存为 PNG 文件。


功能概述

该脚本的主要功能包括:

  1. 读取指定的 ROS Bag 文件。
  2. 从指定的话题(Topic)中提取图像数据。
  3. 使用 OpenCV 将图像保存为 PNG 格式文件。
  4. 提供灵活的命令行参数,支持不同的输入文件、输出目录和话题。

注意:

如果ROS Bag中的图像数据为sensor_msgs/CompressedImage通过以下方式先转换为sensor_msgs/Image,重新录制一个Bag

rosrun image_transport republish compressed in:=/camera/color/image_raw raw out:=/camera/color/image_raw

脚本实现

下面是完整的 Python 脚本代码:

1. 普通RGB(sensor_msgs/Image)图像

#!/usr/bin/env python3
import argparse
import cv2
import os
import rosbag
from sensor_msgs.msg import Image
from cv_bridge import CvBridge

def extract_images_from_bag(bag_file, output_dir, image_topic):
    # 打开rosbag文件
    bag = rosbag.Bag(bag_file, 'r')
    bridge = CvBridge()
    count = 0

    # 读取指定话题的消息
    for topic, msg, t in bag.read_messages(topics=[image_topic]):
        try:
            # 将ROS消息转换为OpenCV图像
            cv_image = bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
        except Exception as e:
            print(f"Error converting image: {e}")
            continue

        # 保存为图像文件
        image_filename = os.path.join(output_dir, f"frame_{count:06d}.png")
        cv2.imwrite(image_filename, cv_image)
        count += 1
        print(f"Image {count} saved to {image_filename}")

    # 关闭rosbag文件
    bag.close()
    print(f"Processed {count} images.")

def main():
    # 使用argparse处理命令行参数
    parser = argparse.ArgumentParser(description="Extract images from a rosbag and save them as files.")
    parser.add_argument("bag_file", help="The rosbag file to extract images from")
    parser.add_argument("output_dir", help="Directory to save the extracted images")
    parser.add_argument("image_topic", help="Image topic to subscribe to")

    args = parser.parse_args()

    # 确保输出目录存在
    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)

    # 从rosbag中提取图像
    extract_images_from_bag(args.bag_file, args.output_dir, args.image_topic)

if __name__ == '__main__':
    main()

2. 8UC3红外图像

#!/usr/bin/env python3
import argparse
import cv2
import os
import rosbag
from sensor_msgs.msg import Image
from cv_bridge import CvBridge

def extract_images_from_bag(bag_file, output_dir, image_topic):
    # 打开rosbag文件
    bag = rosbag.Bag(bag_file, 'r')
    bridge = CvBridge()
    count = 0

    # 读取指定话题的消息
    for topic, msg, t in bag.read_messages(topics=[image_topic]):
        try:
            # 检查图像的编码格式
            if msg.encoding == '8UC3':
                # 直接转换为OpenCV图像
                cv_image = bridge.imgmsg_to_cv2(msg, desired_encoding='passthrough')
            else:
                # 转换为指定的颜色编码(例如 'bgr8')
                cv_image = bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
        except Exception as e:
            print(f"Error converting image: {e}")
            continue

        # 保存为图像文件
        image_filename = os.path.join(output_dir, f"frame_{count:06d}.png")
        cv2.imwrite(image_filename, cv_image)
        count += 1
        print(f"Image {count} saved to {image_filename}")

    # 关闭rosbag文件
    bag.close()
    print(f"Processed {count} images.")

def main():
    # 使用argparse处理命令行参数
    parser = argparse.ArgumentParser(description="Extract images from a rosbag and save them as files.")
    parser.add_argument("bag_file", help="The rosbag file to extract images from")
    parser.add_argument("output_dir", help="Directory to save the extracted images")
    parser.add_argument("image_topic", help="Image topic to subscribe to")

    args = parser.parse_args()

    # 确保输出目录存在
    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)

    # 从rosbag中提取图像
    extract_images_from_bag(args.bag_file, args.output_dir, args.image_topic)

if __name__ == '__main__':
    main()

脚本讲解

1. 依赖库

该脚本依赖以下库:

  • rosbag:用于读取 ROS Bag 文件。
  • cv_bridge:将 ROS 的图像消息转换为 OpenCV 格式。
  • cv2:OpenCV 的核心库,用于图像处理和文件保存。
  • argparse:用于解析命令行参数。

安装依赖库

在运行脚本前,需要确保已安装这些依赖项。以下是安装命令:

pip install opencv-python
sudo apt install python3-rosbag python3-cv-bridge

脚本功能详解

2. 主要功能模块

2.1 从 ROS Bag 中提取图像

extract_images_from_bag 函数是脚本的核心部分,主要完成以下任务:

  1. 读取 Bag 文件
    使用 rosbag.Bag 打开指定的 ROS Bag 文件以便提取数据。

  2. 遍历消息
    使用 bag.read_messages 遍历指定话题中的所有消息。

  3. 转换图像
    借助 cv_bridge 将 ROS 格式的图像消息(sensor_msgs/Image)转换为 OpenCV 格式的图像数据。

  4. 保存图像
    使用 cv2.imwrite 将提取的图像保存为 PNG 文件,文件名格式为 frame_000001.pngframe_000002.png 等。


2.2 命令行参数解析

该脚本使用 argparse 支持灵活的命令行参数配置,支持以下参数:

  • bag_file:输入的 ROS Bag 文件路径。
  • output_dir:指定提取图像保存的目标目录。
  • image_topic:ROS 话题名称,用于指定需要提取图像的话题。

通过这些参数,用户可以灵活配置脚本,处理不同的输入文件、输出路径和图像来源话题。


2.3 确保目录存在

为了确保图像可以正确保存,脚本在保存图像之前会检查目标输出目录是否存在:

  • 如果目录不存在,则使用 os.makedirs 自动创建。
  • 避免因缺少目录导致的保存失败。

3. 运行脚本

使用以下命令运行脚本:

python3 extract_images.py <bag_file> <output_dir> <image_topic>

示例

假设

  • ROS Bag 文件名data.bag
  • 输出目录output
  • 图像话题名称/camera/image_raw

运行脚本的命令

在终端中运行以下命令:

python3 extract_images.py data.bag output /camera/image_raw

输出结果

脚本运行后将执行以下操作:

1. 从指定的话题中提取图像数据:

脚本会读取 ROS Bag 文件中的图像数据,并从指定的话题(例如 /camera/image_raw)中提取图像消息。

2. 保存图像到指定的输出目录:

提取的图像会以 PNG 格式保存在 output 目录中,用户可以通过该目录查看保存的图像文件。

3. 文件命名格式:

图像文件将按照顺序命名为 frame_000001.pngframe_000002.png 等。例如,如果提取了 100 张图像,则会生成文件 frame_000001.pngframe_000100.png

4. 终端输出进度:

每提取一张图像,脚本会在终端输出其保存路径。完成后,还会显示总共提取并保存了多少张图像。


示例输出

Image 1 saved to output/frame_000001.png
Image 2 saved to output/frame_000002.png
Image 3 saved to output/frame_000003.png
...
Processed 100 images.

脚本运行完成后,用户可以在 output 目录中找到所有提取的图像文件。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL通过binlog日志进行数据恢复

记录一次阿里云MySQL通过binlog日志进行数据回滚 问题描述由于阿里云远程mysql没有做安全策略 所以服务器被别人远程攻击把数据库给删除&#xff0c;通过查看binlog日志可以看到进行了drop操作&#xff0c;下面将演示通过binlog日志进行数据回滚操作。 1、查询是否开始binlog …

如何在 Ubuntu 22.04 上安装和使用 Rust 编程语言环境

简介 Rust 是一门由 Mozilla 开发的系统编程语言&#xff0c;专注于性能、可靠性和内存安全。它在没有垃圾收集的情况下实现了内存安全&#xff0c;这使其成为构建对性能要求苛刻的应用程序&#xff08;如操作系统、游戏引擎和嵌入式系统&#xff09;的理想选择。 接下来&…

前端项目初始化搭建(二)

一、使用 Vite 创建 Vue 3 TypeScript 项目 PS E:\web\cursor-project\web> npm create vitelatest yf-blog -- --template vue-ts> npx > create-vite yf-blog --template vue-tsScaffolding project in E:\web\cursor-project\web\yf-blog...Done. Now run:cd yf-…

生活小妙招之UE CaptureRT改

需求&#xff0c;四个不同的相机拍摄结果同屏分屏显示 一般的想法是四个Capture拍四张RT&#xff0c;然后最后在面片/UI上组合。这样的开销是创建4张RT&#xff0c;材质中采样4次RT。 以更省的角度&#xff0c;想要对以上流程做优化&#xff0c;4个相机拍摄是必须的&#xff…

【AIGC进阶-ChatGPT提示词副业解析】探索生活的小确幸:在平凡中寻找幸福

引言 在这个快节奏的现代社会中,我们常常被各种压力和焦虑所困扰,忘记了生活中那些细小而珍贵的幸福时刻。本文将探讨如何在日常生活中发现和珍惜那些"小确幸",以及如何通过尝试新事物来丰富我们的生活体验。我们还将讨论保持神秘感和期待感对于维持生活乐趣的重要性…

C#编程报错- “ComboBox”是“...ComboBox”和“...ComboBox”之间的不明确的引用

1、问题描述 在学习使用C#中的Winform平台编写一个串口助手程序时&#xff0c; 在编写一个更新ComboBox列表是遇到了问题&#xff0c;出错的代码是 2、报错信息 CS1503 参数 2: 无法从“System.Windows.Forms.ComboBox”转换为“System.Windows.Forms.ComboBox” CS1503 …

ollama+open-webui,本地部署自己的大模型

目录 一、效果预览 二、部署ollama 1.ollama说明 2.安装流程 2.1 windows系统 2.1.1下载安装包 2.1.2验证安装结果 2.1.3设置模型文件保存地址 2.1.4拉取大模型镜像 2.2linux系统 2.2.1下载并安装ollama 2.2.2设置环境变量 2.2.3拉取模型文件 三、部署open-webui…

leetcode_203. 移除链表元素

203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 开始写的时候没有想明白的问题 1. 开始我是想头节点 尾节点 中间节点 分开处理 如果删除的是头节点 然后又要删除头节点的后继节点 那么 这样子的话头节点分开处理就毫无意义了 接着是尾节点 开始我定义的是curr h…

【大模型微调学习5】-大模型微调技术LoRA

【大模型微调学习5】-大模型微调技术LoRA LoRa微调1.现有 PEFT 方法的局限与挑战2.LoRA: 小模型有大智慧 (2021)3.AdaLoRA: 自适应权重矩阵的高效微调 (2023)4.QLoRA: 高效微调量化大模型 (2023) LoRa微调 1.现有 PEFT 方法的局限与挑战 Adapter方法&#xff0c;通过增加模型深…

.NET 技术系列 | 通过CreatePipe函数创建管道

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

DS18B20温度传感器(STM32)

一、介绍 DS18B20是一种常见的数字型温度传感器&#xff0c;具备独特的单总线接口方式。其控制命令和数据都是以数字信号的方式输入输出&#xff0c;相比较于模拟温度传感器&#xff0c;具有功能强大、硬件简单、易扩展、抗干扰性强等特点。 传感器参数 测温范围为-55℃到1…

shell编程2 永久环境变量和字符串显位

声明 学习视频来自B站UP主 泷羽sec 常见变量 echo $HOME &#xff08;家目录 root用户&#xff09; /root cd /root windows的环境变量可以去设置里去新建 为什么输入ls dir的命令的时候就会输出相应的内容呢 因为这些命令都有相应的变量 which ls 通过这个命令查看ls命令脚本…

MaskGCT——开源文本转语音模型,可模仿任何人说话声音

前期介绍过很多语音合成的模型&#xff0c;比如ChatTTS&#xff0c;微软语音合成大模型&#xff0c;字节跳动自家发布的语音合成模型Seed-TTS。其模型随着技术的不断发展&#xff0c;模型说话的声音也越来越像人类&#xff0c;虽然 seed-tts 可以进行语音合成等功能&#xff0c…

java全栈day16--Web后端实战(数据库)

一、数据库介绍 二、Mysql安装&#xff08;自行在网上找&#xff0c;教程简单&#xff09; 安装好了进行Mysql连接 连接语法&#xff1a;winr输入cmd&#xff0c;在命令行中再输入mysql -uroot -p密码 方法二&#xff1a;winr输入cmd&#xff0c;在命令行中再输入mysql -uroo…

geoserver 瓦片地图,tomcat和nginx实现负载均衡

在地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;GeoServer作为一个强大的开源服务器&#xff0c;能够发布各种地图服务&#xff0c;包括瓦片地图服务。为了提高服务的可用性和扩展性&#xff0c;结合Tomcat和Nginx实现负载均衡成为了一个有效的解决方案。本文将详细…

达梦8-达梦数据的示例用户和表

1、示例库说明&#xff1a; 创建达梦数据的示例用户和表&#xff0c;导入测试数据。 在完成达梦数据库的安装之后&#xff0c;在/opt/dmdbms/samples/instance_script目录下有用于创建示例用户的SQL文件。samples目录前的路径根据实际安装情况进行修改&#xff0c;本文将达梦…

利用notepad++删除特定关键字所在的行

1、按组合键Ctrl H&#xff0c;查找模式选择 ‘正则表达式’&#xff0c;不选 ‘.匹配新行’ 2、查找目标输入 &#xff1a; ^.*关键字.*\r\n (不保留空行) ^.*关键字.*$ (保留空行)3、替换为&#xff1a;&#xff08;空&#xff09; 配置界面参考下图&#xff1a; ​​…

Qt学习笔记第61到70讲

第61讲 记事本实现当前行高亮功能 实现策略&#xff1a; 获取当前行的光标位置&#xff0c;使用的信号和获取行列值是一样的&#xff0c;即通过ExtraSelection 来配置相关属性。 关键API&#xff1a; QList<QTextEdit::ExtraSelection> extraSelections; void setExtraSe…

Axure高保真数据可视化大屏图表组件库

推出了一款高保真数据可视化大屏图表组件库&#xff0c;旨在为用户提供丰富的图表类型&#xff0c;使数据呈现更加直观、生动。本文将详细介绍该组件库中的各类图表元件&#xff0c;包括面积图、折线图、柱状图、条形图、圆环图、雷达图、仪表图以及综合类图表&#xff0c;以满…

【机器学习】在向量的流光中,揽数理星河为衣,以线性代数为钥,轻启机器学习黎明的瑰丽诗章

文章目录 线性代数入门&#xff1a;机器学习零基础小白指南前言一、向量&#xff1a;数据的基本单元1.1 什么是向量&#xff1f;1.1.1 举个例子&#xff1a; 1.2 向量的表示与维度1.2.1 向量的维度1.2.2 向量的表示方法 1.3 向量的基本运算1.3.1 向量加法1.3.2 向量的数乘1.3.3…