rosbag录制数据与解包
文章目录
- 一、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录制数据与解包相关推荐
- Java做rtp解包封包_基于RTP的H视频数据打包解包类DoubleLi博客园.pdf
基于RTP的H视频数据打包解包类DoubleLi博客园 15- 10-30 基于RTP的H264视频数据打包解包类 - DoubleLi - 博客园 DoubleLi 博客园 :: 首页 :: 博问 ...
- [数据讨论][解包相关]下江小春也能轻松掌握的碧蓝档案提取工具
注意 请先查看前置内容 下江小春也能看懂的碧蓝档案轻松解包思路 引言 朝禊佬在"下江小春也能看懂的碧蓝档案轻松解包思路"一文中提到了CG.BGM.卡池预览视频等提取方法: 这一部分 ...
- 【FFMPEG】基于RTP的H264视频数据打包解包类
最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包.解包的文档和代码.功夫不负有心人,找到不少有价值的文档和代码.参考这些资料,写了H264 RTP打包类.解包类,实现 ...
- 数据封包解包协议之TCP封包解包
数据封包协议规定:整个数据包包含2字节长度信息+数据包体.2字节长度信息包含本身着2字节.如:数据体是(abcdefg)7个字节,整体封包就是09abcdefg,总共是9个字节的协议 1.netbus ...
- [Python]网络打解包
Python与C.C++交互的时候,如果进行网络消息的收发,需要讲数据打包解包为字节流. 这时候就会用到Struct模块中的pack.unpack函数 打包: PKG = ''# '!' means ...
- 自定义8583模板,打包解包,使用j8583包
j8583_boss.xml <?xml version="1.0" encoding="UTF-8"?> <?xml version=&qu ...
- 自定义8583模板,打包解包,使用j8583包有改动
j8583_boss.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE j8583-c ...
- python教程:dict字典常用方法总结,数据解构(解包)
dict {'name':'holle'}字典存储大量关联型数据,可迭代的,最多只有200个键.查询数据速度非常快,符合二分查找(有100个数比如找75会先找到50然后判断,所以2^7次方7次即可找到 ...
- Lua学习教程之 可变參数数据打包与解包
利用table的pack与unpack进行数据打包与解包.測试代码例如以下: print("Test table.pack()----------------");function ...
最新文章
- SQL 中循环、for循环、游标
- php中堆和栈的使用
- linux: convmv =-======pkgs.org
- 信道容量与Shannon公式
- 需求评审五个维度框架分析及其带来的启示-5-结束语
- session或者error引起的iframe嵌套问题的解决
- 19个必须知道的Visual Studio快捷键
- WordPress 后台评论如何自定义搜索条件
- 知识图谱属性与关系区别
- Centos 7镜像官网下载
- 【gcc】warning信息梳理
- mt6735 [AT Command] AP下发AT+CLAC命令后 ,手机出现宕机
- Gmail邮箱登陆问题解决方案
- python日程提醒小程序_用Python写个爬虫小程序,给女朋友每日定时推送睡前小故事...
- lvs工作在第几层_四层负载均衡——LVS
- payjs插件php,基于payjs的discuz支付插件制作
- 计算机网络技术课程答案网课,《计算机网络技术》大学生网课答案.docx
- python爬取B站评论制作词云
- Node.js 和npm的安装(插件的安装)
- 中国集成电路产业投资建议与十四五需求规模分析报告2022版