本文档整理了从 ROS 2 数据录制,到将图像 topic 导出并转换为 MP4 (H.264 encoded) 视频的完整流程。
适用环境:
ROS 2 Jazzy
bag 存储格式mcap
图像 topic 类型sensor_msgs/msg/Image
当前项目示例 topic/fays/atrak/cam_rgb
目标输出要求:
视频格式MP4
视频编码H.264
不接受H.265 / HEVC
不接受:原始 PNG/JPEG 图片序列直接提交
1. 录制 ROS 2 Bag
1.1 录制指定 topic
ros2 bag record -o my_bag /fays/atrak/cam_rgb /fays/atrak/cam_stereo /fays/atrak/imu
命令说明:
ros2 bag record:启动 ROS 2 bag 录制。
-o my_bag:指定输出目录名为 my_bag。
/fays/atrak/cam_rgb /fays/atrak/cam_stereo /fays/atrak/imu:指定需要录制的 topic。
录制完成后,通常会生成一个目录,例如:
my_bag/
目录中会包含 .mcap 文件和元数据文件。
1.2 录制全部 topic
ros2 bag record -a
命令说明:
- -a:表示录制当前系统中所有正在发布的 topic。
1.3 排除某些 topic
ros2 bag record -a -x "/tf|/tf_static"
命令说明:
-x:使用正则表达式排除不想录制的 topic。
"/tf|/tf_static":排除 /tf 和 /tf_static。
2. 查看 Bag 内容
录制完成后,可以先查看 bag 中包含哪些 topic。
ros2 bag info /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19
命令说明:
ros2 bag info:查看 bag 的元信息。
输出中通常包含:
录制时长
消息总数
存储格式
每个 topic 的名称、类型、消息数量
本项目示例中,图像相关 topic 为:
/fays/atrak/cam_rgb
/fays/atrak/cam_stereo
其中更适合直接导出视频的是:
/fays/atrak/cam_rgb
3. 播放 Bag
3.1 正常播放
ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19
命令说明:
ros2 bag play:重新发布 bag 中记录的消息。
播放时,原始 topic 会再次出现在 ROS 网络中。
注意:
该命令不会自动打开新终端。
该命令不会自动显示图像窗口。
它只是把录制时的消息重新发出来。
3.2 循环播放
ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --loop
命令说明:
- --loop:播放到结尾后重新从头播放。
这个参数在 bag 时间较短时非常有用。当前示例 bag 时长约 38.8 秒,不加 --loop 时,播放完会自动结束。
3.3 降低播放速度
ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --rate 0.5
命令说明:
--rate 0.5:按 0.5 倍速播放。
原始 38 秒的数据会被拉长到大约 76 秒,更方便调试和导出。
4. 检查 Topic 是否在发布
在播放 bag 时,可以打开另一个终端检查 topic 是否正常发布。
4.1 列出当前所有 topic
ros2 topic list
命令说明:
- ros2 topic list:查看当前 ROS 网络中所有可见 topic。
如果播放正常,你应看到类似:
/fays/atrak/cam_rgb
/fays/atrak/cam_stereo
/fays/atrak/imu
4.2 查看 topic 类型和订阅情况
ros2 topic info /fays/atrak/cam_rgb
命令说明:
ros2 topic info:查看某个 topic 的详细信息。
输出中可看到:
消息类型
发布者数量
订阅者数量
4.3 查看消息频率
ros2 topic hz /fays/atrak/cam_rgb
命令说明:
ros2 topic hz:统计某个 topic 的发布频率。
若有稳定频率输出,说明数据正在持续发布。
4.4 打印一条消息
ros2 topic echo /fays/atrak/cam_rgb --once
命令说明:
ros2 topic echo:打印消息内容。
--once:只打印一条后退出。
该命令可用于快速确认图像消息确实存在。
5. 导出图像序列
5.1 为什么不直接用 image_view extract_images
在当前 Jazzy 环境中,执行:
ros2 run image_view extract_images --ros-args -r image:=/fays/atrak/cam_rgb
会报错:
ParameterNotDeclaredException: transport
这说明该工具在当前环境下存在参数兼容问题,不适合作为稳定方案。
因此,改为使用一个自定义 Python 节点直接订阅图像并保存为 JPG。
5.2 导出脚本位置
当前项目中已创建脚本:
/home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py
该脚本功能:
订阅 /fays/atrak/cam_rgb
将每一帧保存到:
/home/kvzjj/project/fays_vikit_ros_ws1/export_rgb
- 文件名格式:
frame000000.jpg
frame000001.jpg
frame000002.jpg
5.3 运行导出脚本
在一个终端中执行:
python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py
命令说明:
python3:使用系统 Python 运行脚本。
脚本会持续订阅 /fays/atrak/cam_rgb 并保存图片。
5.4 播放 bag 让脚本接收图像
在另一个终端执行:
ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --loop
建议使用 --loop,原因是:
bag 总时长较短
如果导出脚本启动稍晚,仍然可以在下一轮收到数据
5.5 检查图片是否成功导出
ls /home/kvzjj/project/fays_vikit_ros_ws1/export_rgb
命令说明:
ls:列出导出目录中的文件。
如果看到大量连续编号的 JPG,说明导出成功。
6. 将图片序列转为 MP4(H.264)
6.1 转码命令
ffmpeg -framerate 34 -i /home/kvzjj/project/fays_vikit_ros_ws1/export_rgb/frame%06d.jpg -c:v libx264 -crf 18 -preset medium -pix_fmt yuv420p /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
命令说明:
ffmpeg:多媒体转码工具。
-framerate 34:按每秒 34 帧读取图片序列。
-i .../frame%06d.jpg:输入图片序列。
%06d:表示 6 位数字编号,例如 000001。
-c:v libx264:使用 H.264 编码器。
-crf 18:设置较高画质,数值越小质量越高。
-preset medium:编码速度和压缩率折中。
-pix_fmt yuv420p:保证较好的播放器兼容性。
output_rgb_h264.mp4:输出文件名。
6.2 为什么要用 yuv420p
有些播放器或评测平台对像素格式有要求。使用:
-pix_fmt yuv420p
通常能获得最好的兼容性。
6.3 为什么帧率设置为 34
根据 bag 中图像数量和总时长,实际帧率大约在 33 到 34 FPS 左右,因此这里采用:
-framerate 34
如果后续需要更慢或更快的展示速度,可以调整该参数,例如:
30
25
20
7. 验证输出视频是否符合要求
执行:
ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
命令说明:
- ffprobe:用于查看媒体文件的详细信息。
在输出中应看到类似:
Video: h264
这说明:
容器格式是 MP4
视频编码是 H.264
这才符合提交要求。
8. 完整推荐操作顺序
8.1 如果你还没有录制 bag
ros2 bag record -o my_bag /fays/atrak/cam_rgb /fays/atrak/cam_stereo /fays/atrak/imu
8.2 查看 bag 信息
ros2 bag info /path/to/my_bag
8.3 启动图像导出脚本
python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py
8.4 播放 bag
ros2 bag play /path/to/my_bag --loop
8.5 导出完成后转 MP4
ffmpeg -framerate 34 -i /home/kvzjj/project/fays_vikit_ros_ws1/export_rgb/frame%06d.jpg -c:v libx264 -crf 18 -preset medium -pix_fmt yuv420p /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
8.6 验证输出格式
ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
9. 依赖安装
如果缺少相关工具,可安装:
sudo apt update
sudo apt install ros-jazzy-cv-bridge python3-opencv ffmpeg
命令说明:
ros-jazzy-cv-bridge:用于 ROS 图像消息与 OpenCV 图像互转。
python3-opencv:OpenCV Python 接口,用于保存 JPG。
ffmpeg:将图片序列编码为 MP4(H.264)。
10. 常见问题
10.1 为什么 ros2 bag play 没有弹出新窗口
因为该命令只负责发布 topic,不会:
自动打开新终端
自动显示图像窗口
自动开始导出图片
你需要手动打开第二个终端,执行接收图像的程序。
10.2 为什么播放一会儿就停了
因为 bag 本身时长有限。播放到末尾后会自动结束,这是正常行为。
解决方法:
ros2 bag play /path/to/bag --loop
10.3 为什么 image_view extract_images 报错
当前 Jazzy 环境下出现:
ParameterNotDeclaredException: transport
因此本文档采用了自定义导出脚本替代该工具。
10.4 为什么最终不能直接提交 JPG 序列
因为要求是:
MP4
H.264 encoded
单独的 JPG/PNG 帧不满足提交格式要求。
11. 本项目当前可直接使用的命令
11.1 导出图片
终端 1:
python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py
终端 2:
ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --loop
11.2 转 MP4(H.264)
ffmpeg -framerate 34 -i /home/kvzjj/project/fays_vikit_ros_ws1/export_rgb/frame%06d.jpg -c:v libx264 -crf 18 -preset medium -pix_fmt yuv420p /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
11.3 验证格式
ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4
如果输出中包含 Video: h264,则结果符合要求。
ROS 2 Bag 录制与转 MP4 操作说明
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法