有时 .bag 文件包含多个您想提取的视频, 例如使用 D435i 录制 RGB 和 Depth视频并打包成.bag文件. 一种简单的方法来在bag 文件里提取您需要的视频。
参考链接:https://gist.github.com/wngreene/835cda68ddd9c5416defce876a4d7dd9
一、测试环境
本人使用 Ubuntu 20.04 LTS
二、前置要求
下好 ROS Noetic (只要是ROS1,问题都不大)
安装依赖包:
1. ffmpeg
sudo apt install ffmpeg
2. Opencv, roslib, sensor-msgs
sudo apt install python3-roslib python3-sensor-msgs python3-opencv
三、bag_to_images.py源码
你可以在 GitHub 下载,或复制下面的代码。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2016 Massachusetts Institute of Technology
"""Extract images from a rosbag.
"""
import os
import argparse
import cv2
import rosbag
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
def main():
"""Extract a folder of images from a rosbag.
"""
parser = argparse.ArgumentParser(description="Extract images from a ROS bag.")
parser.add_argument("bag_file", help="Input ROS bag.")
parser.add_argument("output_dir", help="Output directory.")
parser.add_argument("image_topic", help="Image topic.")
args = parser.parse_args()
print "Extract images from %s on topic %s into %s" % (args.bag_file,
args.image_topic, args.output_dir)
bag = rosbag.Bag(args.bag_file, "r")
bridge = CvBridge()
count = 0
for topic, msg, t in bag.read_messages(topics=[args.image_topic]):
cv_img = bridge.imgmsg_to_cv2(msg, desired_encoding="passthrough")
cv2.imwrite(os.path.join(args.output_dir, "frame%06i.png" % count), cv_img)
print "Wrote image %i" % count
count += 1
bag.close()
return
if __name__ == '__main__':
main()
把 bag_to_images.py (上面的代码,我更改了文件名), 保存图像的文件, 和你的bag文件放到同一個地方。
四、查看 .bag文件的topics 和抽取视频為图片
bag文件里不一定是你想要的東西,要自己去看。下面是你查看 bag文件的命令行。
rosbag info location1.bag
把 location1.bag 換成你自己的就可以了. 下面是打開之後。
假如紅色圈起来的, 是我要的东西 Depth视频. 当我们知道topic (/device_0sensor_0/Depth_0/image/data) 叫什么之后,我们就要把他们抽出来就要用到 extract.py跟運作下面的命令行。
python3 bag_to_images.py bag文件 保存图像的文件 你要的topics
命令行會把你的视频在文件里, 以图片的方式保留下来。
五、把图片转化为 mp4
ffmpeg -framerate 30 -pattern_type glob -i 保存图像的文件/'*.png' -c:v libx264 -pix_fmt yuv420p 生成视频名稱.mp4