文章目录

  • 一、rosbag录制数据
  • 二、bag数据播放
  • 三、bag解包出图像数据(三种方式)
    • 1.ROS Wiki提供的roslaunch文件解包
    • 2.python解包
    • 3.用kalibr的一个工具解包
  • 总结

一、rosbag录制数据

使用rosbag record命令

rosbag record -O [bag_name] [topic1] [topic2] [...]    #不加中括号

-O大写,后面对录制的bag命名,再之后跟要录制的topic名字(用rostopic list查询当前所有的topic)。

录制结束后,在当前shell所在路径会生成后缀为.bag的数据包,使用rosbag info来查看该数据包的信息

rosbag info [bag_file]    #不加中括号

应该会输出该bag存储的topic名字和帧数,如果报错,说明该包有损坏(常见于U盘拷贝的情况)。正常输出类似于下面这样:

tips:这里顺便记录一下rostopic的用法
查看当前所有的topic:rostopic list
查看某个topic的输出:rostopic echo [topic_name]
查看某个topic的发布频率:rostopic hz [topic_name]
查看某个topic的数据格式:rostopic echo [topic_name]/encoding

二、bag数据播放

用rosbag play命令

rosbag play [bag_file]    #不加中括号

播放的意思是指将bag所记录的所有内容重新进行了一遍,按空格暂停和继续。播放时可在rviz里add相应的topic进行查看。

三、bag解包出图像数据(三种方式)

参考链接https://www.codeleading.com/article/11362024892/的内容,这里介绍两种解包的方法。

1.ROS Wiki提供的roslaunch文件解包

新建launch文件(文件在哪无所谓) : bag2img.launch

<launch><node pkg="rosbag" type="play" name="rosbag" required="true" args="/home/user/test1.bag"/><node name="extract" pkg="image_view" type="extract_images" respawn="false" required="true" output="screen" cwd="ROS_HOME"><remap from="image" to="/zed2/zed_node/depth/depth_registered"/><param name="sec_per_frame" value="0.03"/></node></launch>

args="/home/user/test1.bag"是bag的存放路径,"/zed2/zed_node/depth/depth_registered"是要解析的topic名称。
**< param name=“sec_per_frame” value=“0.03”/>**这句话是说,以每一帧花费0.03s的时间,这个条件对你的bag文件进行图像提取,如果没有这句话,就是默认0.1s,也就是没秒10帧的速率对图像提取。经过我的测试发现,无论怎么调整这个值,都无法跟bag文件中的信息数目匹配,因此来说,这种方法存在一定的图像缺失的情况,只能无限接近袁原始图像的数目,比如我的原始数据有640帧,但经过调整sec_per_frame的值,最高的时候还是只能到639,多数情况下到637,默认值0.1的时候,只有200多张图像。原因是实际录制时相机的帧率不是绝对稳定的,而解析时设置了固定的时间间隔,这个误差会累积下去,帧数越多,最后漏掉的就越多。

运行roslaunch:

roslaunch bag2img.launch

提取成功的图像存储在home文件夹下的.ros文件夹下,一般是隐藏的文件夹,使用crtl+h可显示出来。

优点:操作简单,使用ros即可;缺点:提取信息与原始录制的信息并不完全一致,主要体现在提取的图片数量和ros录制的时候的信息数量不一致,会少。此外,不含有时间戳;

2.python解包

通过编写Python程序按照我们想要的信息及方式来提取,在与bag文件同级目录下建立.py文件(方便操作,若不是同级目录,下面代码中要写绝对路径)

代码如下(示例):

# coding:utf-8
#!/usr/bin/python# Extract images from a bag file.#PKG = 'beginner_tutorials'
import roslib;   #roslib.load_manifest(PKG)
import rosbag
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError# Reading bag filename from command line or roslaunch parameter.
#import os
#import sysrgb_path = '/home/david/workspace/bags/rgb/'   #已经建立好的存储rgb彩色图文件的目录
depth_path= '/home/david/workspace/bags/depth/' # 已经建立好的存储深度图文件的目录class ImageCreator():def __init__(self):self.bridge = CvBridge()with rosbag.Bag('/home/andy/bag_folder/file_name.bag', 'r') as bag:  #要读取的bag文件;for topic,msg,t in bag.read_messages():if topic == "camera/rgb/image_raw": #图像的topic;try:cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")except CvBridgeError as e:print etimestr = "%.6f" %  msg.header.stamp.to_sec()#%.6f表示小数点后带有6位,可根据精确度需要修改;image_name = timestr+ ".png" #图像命名:时间戳.pngcv2.imwrite(rgb_path + image_name, cv_image)  #保存;elif topic == "camera/depth_registered/image_raw": #图像的topic;try:cv_image = self.bridge.imgmsg_to_cv2(msg,"16UC1")except CvBridgeError as e:print etimestr = "%.6f" %  msg.header.stamp.to_sec()#%.6f表示小数点后带有6位,可根据精确度需要修改;image_name = timestr+ ".png" #图像命名:时间戳.pngcv2.imwrite(depth_path + image_name, cv_image)  #保存;if __name__ == '__main__':#rospy.init_node(PKG)try:image_creator = ImageCreator()except rospy.ROSInterruptException:pass

上边这段代码是原博客给的,我又根据自己需求改了一份,同时解析双目rgb和深度图,其中深度图的存储格式由默认的uint8改为float(而且我的深度图是32FC1格式的,不是16UC1)
代码如下:

# coding:utf-8
#!/usr/bin/python# Extract images from a bag file.#PKG = 'beginner_tutorials'
import roslib;   #roslib.load_manifest(PKG)
import rosbag
import rospy
import cv2
import sys
import numpy as np
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError# Reading bag filename from command line or roslaunch parameter.
#import os
#import sysrgb_path_left = '/home/user/dynamic_data/left/'
rgb_path_right = '/home/user/dynamic_data/right/'   #已经建立好的存储rgb彩色图文件的目录
depth_path= '/home/user/dynamic_data/depth_pfm/' # 已经建立好的存储深度图文件的目录class ImageCreator():def __init__(self):self.bridge = CvBridge()with rosbag.Bag('/home/user/test1.bag', 'r') as bag:  #要读取的bag文件;for topic,msg,t in bag.read_messages():if topic == "/zed2/zed_node/left_raw/image_raw_color": #图像的topic;try:cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")except CvBridgeError as e:print (e)timestr = "%.6f" %  msg.header.stamp.to_sec()#%.6f表示小数点后带有6位,可根据精确度需要修改;image_name = timestr+ ".png" #图像命名:时间戳.pngcv2.imwrite(rgb_path_left + image_name, cv_image)  #保存;elif topic == "/zed2/zed_node/right_raw/image_raw_color": #图像的topic;try:cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")except CvBridgeError as e:print (e)timestr = "%.6f" %  msg.header.stamp.to_sec()#%.6f表示小数点后带有6位,可根据精确度需要修改;image_name = timestr+ ".png" #图像命名:时间戳.pngcv2.imwrite(rgb_path_right + image_name, cv_image)  #保存;elif topic == "/zed2/zed_node/depth/depth_registered": #图像的topic;try:cv_image = self.bridge.imgmsg_to_cv2(msg,"32FC1")except CvBridgeError as e:print (e)timestr = "%.6f" %  msg.header.stamp.to_sec()#%.6f表示小数点后带有6位,可根据精确度需要修改;image_name = timestr+ ".pfm" #图像命名:时间戳.png# print('image max:',np.max(cv_image))# cv2.imwrite(depth_path + image_name, cv_image)  #保存;write_pfm(depth_path + image_name, cv_image)def write_pfm(path, image, scale=1):"""Write pfm file.Args:path (str): pathto fileimage (array): datascale (int, optional): Scale. Defaults to 1."""with open(path, "wb") as file:color = Noneif image.dtype.name != "float32":raise Exception("Image dtype must be float32.")image = np.flipud(image)if len(image.shape) == 3 and image.shape[2] == 3:  # color imagecolor = Trueelif (len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1):  # greyscalecolor = Falseelse:raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")file.write("PF\n" if color else "Pf\n".encode())file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))endian = image.dtype.byteorderif endian == "<" or endian == "=" and sys.byteorder == "little":scale = -scalefile.write("%f\n".encode() % scale)image.tofile(file)if __name__ == '__main__':#rospy.init_node(PKG)try:image_creator = ImageCreator()except rospy.ROSInterruptException:pass

优点:没有信息损失,完全按照你录制的数据完整提取,且具有时间戳。缺点:使用python2,要装一些库,如OpenCV

3.用kalibr的一个工具解包

https://github.com/ethz-asl/kalibr/wiki/bag-format.
kalibr里的这个东西不仅可以从bag里解出image、IMU信息,还能把image、IMU信息打包成bag格式。但是kalibr解包出的image是灰度图(kalibr本身是一个标定工具,标定用的是灰度图)。

关于解包这块,问了高手,他们都是自己写的代码订阅某个topic,每收到一个message就做一次输出,避免了官方给的launch文件定时提取造成的漏帧BUG。自己写个也挺好,这玩意复用性还挺强的。


总结

算是记录一下rosbag的一些常见用法,包括录制,播放,解包。
这里还有个链接,里面介绍了rosbag一些更丰富的功能:
http://zhaoxuhui.top/blog/2021/02/24/ros-bag-processing-scripts.html.

rosbag录制数据与解包相关推荐

  1. Java做rtp解包封包_基于RTP的H视频数据打包解包类DoubleLi博客园.pdf

    基于RTP的H视频数据打包解包类DoubleLi博客园 15- 10-30 基于RTP的H264视频数据打包解包类 - DoubleLi - 博客园 DoubleLi 博客园 :: 首页 :: 博问 ...

  2. [数据讨论][解包相关]下江小春也能轻松掌握的碧蓝档案提取工具

    注意 请先查看前置内容 下江小春也能看懂的碧蓝档案轻松解包思路 引言 朝禊佬在"下江小春也能看懂的碧蓝档案轻松解包思路"一文中提到了CG.BGM.卡池预览视频等提取方法: 这一部分 ...

  3. 【FFMPEG】基于RTP的H264视频数据打包解包类

    最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包.解包的文档和代码.功夫不负有心人,找到不少有价值的文档和代码.参考这些资料,写了H264 RTP打包类.解包类,实现 ...

  4. 数据封包解包协议之TCP封包解包

    数据封包协议规定:整个数据包包含2字节长度信息+数据包体.2字节长度信息包含本身着2字节.如:数据体是(abcdefg)7个字节,整体封包就是09abcdefg,总共是9个字节的协议 1.netbus ...

  5. [Python]网络打解包

    Python与C.C++交互的时候,如果进行网络消息的收发,需要讲数据打包解包为字节流. 这时候就会用到Struct模块中的pack.unpack函数 打包: PKG = ''# '!' means ...

  6. 自定义8583模板,打包解包,使用j8583包

    j8583_boss.xml <?xml version="1.0" encoding="UTF-8"?> <?xml version=&qu ...

  7. 自定义8583模板,打包解包,使用j8583包有改动

    j8583_boss.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE j8583-c ...

  8. python教程:dict字典常用方法总结,数据解构(解包)

    dict {'name':'holle'}字典存储大量关联型数据,可迭代的,最多只有200个键.查询数据速度非常快,符合二分查找(有100个数比如找75会先找到50然后判断,所以2^7次方7次即可找到 ...

  9. Lua学习教程之 可变參数数据打包与解包

    利用table的pack与unpack进行数据打包与解包.測试代码例如以下: print("Test table.pack()----------------");function ...

最新文章

  1. SQL 中循环、for循环、游标
  2. php中堆和栈的使用
  3. linux: convmv =-======pkgs.org
  4. 信道容量与Shannon公式
  5. 需求评审五个维度框架分析及其带来的启示-5-结束语
  6. session或者error引起的iframe嵌套问题的解决
  7. 19个必须知道的Visual Studio快捷键
  8. WordPress 后台评论如何自定义搜索条件
  9. 知识图谱属性与关系区别
  10. Centos 7镜像官网下载
  11. 【gcc】warning信息梳理
  12. mt6735 [AT Command] AP下发AT+CLAC命令后 ,手机出现宕机
  13. Gmail邮箱登陆问题解决方案
  14. python日程提醒小程序_用Python写个爬虫小程序,给女朋友每日定时推送睡前小故事...
  15. lvs工作在第几层_四层负载均衡——LVS
  16. payjs插件php,基于payjs的discuz支付插件制作
  17. 计算机网络技术课程答案网课,《计算机网络技术》大学生网课答案.docx
  18. python爬取B站评论制作词云
  19. Node.js 和npm的安装(插件的安装)
  20. 中国集成电路产业投资建议与十四五需求规模分析报告2022版

热门文章

  1. 软件测试工程师常见面试题和笔试题
  2. 查看虚拟机里的Centos7的IP
  3. APS系统在企业生产中的场景应用
  4. 我认识的林家翘先生 转载
  5. 推荐一本书 selenium2+python自动化-作者虫师
  6. STM32单片机与Openmv的串口通信
  7. ros----键盘控制机器人(2)【键盘控制文件书写】
  8. hadoop2.8.2 YARN 架构
  9. 安卓上微信闪退的一种解决方法
  10. mysql timestamp 默认_MySQL数据库TIMESTAMP怎么设置默认值 | 学步园