本文档整理了从 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,则结果符合要求。