本文档整理了从 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

```bash

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。

录制完成后,通常会生成一个目录,例如:

```bash

my_bag/

```

目录中会包含 .mcap 文件和元数据文件。

### 1.2 录制全部 topic

```bash

ros2 bag record -a

```

命令说明:

- -a:表示录制当前系统中所有正在发布的 topic。

### 1.3 排除某些 topic

```bash

ros2 bag record -a -x "/tf|/tf_static"

```

命令说明:

- -x:使用正则表达式排除不想录制的 topic。

- "/tf|/tf_static":排除 /tf/tf_static

## 2. 查看 Bag 内容

录制完成后,可以先查看 bag 中包含哪些 topic。

```bash

ros2 bag info /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19

```

命令说明:

- ros2 bag info:查看 bag 的元信息。

- 输出中通常包含:

- 录制时长

- 消息总数

- 存储格式

- 每个 topic 的名称、类型、消息数量

本项目示例中,图像相关 topic 为:

```bash

/fays/atrak/cam_rgb

/fays/atrak/cam_stereo

```

其中更适合直接导出视频的是:

```bash

/fays/atrak/cam_rgb

```

## 3. 播放 Bag

### 3.1 正常播放

```bash

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 循环播放

```bash

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 降低播放速度

```bash

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

```bash

ros2 topic list

```

命令说明:

- ros2 topic list:查看当前 ROS 网络中所有可见 topic。

如果播放正常,你应看到类似:

```bash

/fays/atrak/cam_rgb

/fays/atrak/cam_stereo

/fays/atrak/imu

```

### 4.2 查看 topic 类型和订阅情况

```bash

ros2 topic info /fays/atrak/cam_rgb

```

命令说明:

- ros2 topic info:查看某个 topic 的详细信息。

- 输出中可看到:

- 消息类型

- 发布者数量

- 订阅者数量

### 4.3 查看消息频率

```bash

ros2 topic hz /fays/atrak/cam_rgb

```

命令说明:

- ros2 topic hz:统计某个 topic 的发布频率。

- 若有稳定频率输出,说明数据正在持续发布。

### 4.4 打印一条消息

```bash

ros2 topic echo /fays/atrak/cam_rgb --once

```

命令说明:

- ros2 topic echo:打印消息内容。

- --once:只打印一条后退出。

该命令可用于快速确认图像消息确实存在。

## 5. 导出图像序列

### 5.1 为什么不直接用 image_view extract_images

在当前 Jazzy 环境中,执行:

```bash

ros2 run image_view extract_images --ros-args -r image:=/fays/atrak/cam_rgb

```

会报错:

```text

ParameterNotDeclaredException: transport

```

这说明该工具在当前环境下存在参数兼容问题,不适合作为稳定方案。

因此,改为使用一个自定义 Python 节点直接订阅图像并保存为 JPG。

### 5.2 导出脚本位置

当前项目中已创建脚本:

```bash

/home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py

```

该脚本功能:

- 订阅 /fays/atrak/cam_rgb

- 将每一帧保存到:

```bash

/home/kvzjj/project/fays_vikit_ros_ws1/export_rgb

```

- 文件名格式:

```bash

frame000000.jpg

frame000001.jpg

frame000002.jpg

```

### 5.3 运行导出脚本

在一个终端中执行:

```bash

python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py

```

命令说明:

- python3:使用系统 Python 运行脚本。

- 脚本会持续订阅 /fays/atrak/cam_rgb 并保存图片。

### 5.4 播放 bag 让脚本接收图像

在另一个终端执行:

```bash

ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --loop

```

建议使用 --loop,原因是:

- bag 总时长较短

- 如果导出脚本启动稍晚,仍然可以在下一轮收到数据

### 5.5 检查图片是否成功导出

```bash

ls /home/kvzjj/project/fays_vikit_ros_ws1/export_rgb

```

命令说明:

- ls:列出导出目录中的文件。

- 如果看到大量连续编号的 JPG,说明导出成功。

## 6. 将图片序列转为 MP4(H.264)

### 6.1 转码命令

```bash

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

有些播放器或评测平台对像素格式有要求。使用:

```bash

-pix_fmt yuv420p

```

通常能获得最好的兼容性。

### 6.3 为什么帧率设置为 34

根据 bag 中图像数量和总时长,实际帧率大约在 33 到 34 FPS 左右,因此这里采用:

```bash

-framerate 34

```

如果后续需要更慢或更快的展示速度,可以调整该参数,例如:

- 30

- 25

- 20

## 7. 验证输出视频是否符合要求

执行:

```bash

ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4

```

命令说明:

- ffprobe:用于查看媒体文件的详细信息。

在输出中应看到类似:

```text

Video: h264

```

这说明:

- 容器格式是 MP4

- 视频编码是 H.264

这才符合提交要求。

## 8. 完整推荐操作顺序

### 8.1 如果你还没有录制 bag

```bash

ros2 bag record -o my_bag /fays/atrak/cam_rgb /fays/atrak/cam_stereo /fays/atrak/imu

```

### 8.2 查看 bag 信息

```bash

ros2 bag info /path/to/my_bag

```

### 8.3 启动图像导出脚本

```bash

python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py

```

### 8.4 播放 bag

```bash

ros2 bag play /path/to/my_bag --loop

```

### 8.5 导出完成后转 MP4

```bash

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 验证输出格式

```bash

ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4

```

## 9. 依赖安装

如果缺少相关工具,可安装:

```bash

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 本身时长有限。播放到末尾后会自动结束,这是正常行为。

解决方法:

```bash

ros2 bag play /path/to/bag --loop

```

### 10.3 为什么 image_view extract_images 报错

当前 Jazzy 环境下出现:

```text

ParameterNotDeclaredException: transport

```

因此本文档采用了自定义导出脚本替代该工具。

### 10.4 为什么最终不能直接提交 JPG 序列

因为要求是:

- MP4

- H.264 encoded

单独的 JPG/PNG 帧不满足提交格式要求。

## 11. 本项目当前可直接使用的命令

### 11.1 导出图片

终端 1:

```bash

python3 /home/kvzjj/project/fays_vikit_ros_ws1/scripts/export_rgb_images.py

```

终端 2:

```bash

ros2 bag play /home/kvzjj/project/fays_vikit_ros_ws1/rosbag2_2026_04_16-16_08_19 --loop

```

### 11.2 转 MP4(H.264)

```bash

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 验证格式

```bash

ffprobe /home/kvzjj/project/fays_vikit_ros_ws1/output_rgb_h264.mp4

```

如果输出中包含 Video: h264,则结果符合要求。