广告
返回顶部
首页 > 资讯 > 后端开发 > Python >如何将bag文件批量转成mp4
  • 357
分享到

如何将bag文件批量转成mp4

2024-04-02 19:04:59 357人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录简介DockerfileBuild docker imageBuild docker containerRun scriptSource codebag2video.pymain

简介

这篇博客涉及的脚本用来将bag文件批量转化为mp4文件

dockerfile

FROM osrf/ros:kinetic-desktop-full
RUN sudo apt update && \
    sudo apt install -y FFmpeg

Build docker image

docker build -t ros/kinetic:latest .

Build docker container

这里链接的数据卷,要换成你自己的本地路径。容器路径也可以自定义。

docker run -it -v /C/yp/project/realsense2video:/test ros/kinetic:latest

Run script

cd ${your project root}
python main.py --data_root /test/data --out_root /test/save --fps 25
param data_root:包含bag的文件夹
param out_root:输出目录
param fps:每秒的帧数

Source code

bag2video.py

# -*- coding: utf-8 -*-
 
#!/usr/bin/env Python2
 
import roslib
#roslib.load_manifest('rosbag')
import rospy
import rosbag
import sys, getopt
import os
from sensor_msgs.msg import CompressedImage  #压缩图片
from sensor_msgs.msg import Image
import cv2
 
import numpy as np
 
import shlex, subprocess  #读取命令行参数
#subprocess 是一个 python 标准类库,用于创建进程运行系统命令,并且可以连接进程的输入输出和
#错误管道,获取它们的返回,使用起来要优于 os.system,在这里我们使用这个库运行 Hive 语句并获取返回结果。
 
#shlex 是一个 python 标准类库,使用这个类我们可以轻松的做出对 linux shell 的词法分析,在
#这里我们将格式化好的 hive 连接语句用 shlex 切分,配合 subprocess.run 使用。
MJPEG_VIDEO = 1
RAWIMAGE_VIDEO = 2
VIDEO_CONVERTER_TO_USE = "ffmpeg" # or you may want to use "avconv" #视频转换器
 
def print_help():
    print('rosbag2video.py [--fps 25] [--rate 1] [-o outputfile] [-v] [-s] [-t topic] bagfile1 [bagfile2] ...')
    print()
    print('Converts image sequence(s) in ros bag file(s) to video file(s) with fixed frame rate using',VIDEO_CONVERTER_TO_USE)
    print(VIDEO_CONVERTER_TO_USE,'needs to be installed!')
    print()
    print('--fps   Sets FPS value that is passed to',VIDEO_CONVERTER_TO_USE)
    print('        Default is 25.')
    print('-h      Displays this help.')
    print('--ofile (-o) sets output file name.')
    print('        If no output file name (-o) is given the filename \'<prefix><topic>.mp4\' is used and default output codec is h264.')
    print('        Multiple image topics are supported only when -o option is _not_ used.')
    print('        ',VIDEO_CONVERTER_TO_USE,' will guess the fORMat according to given extension.')
    print('        Compressed and raw image messages are supported with mono8 and bgr8/rgb8/bggr8/rggb8 formats.')
    print('--rate  (-r) You may slow down or speed up the video.')
    print('        Default is 1.0, that keeps the original speed.')
    print('-s      Shows each and every image extracted from the rosbag file (cv_bride is needed).')
    print('--topic (-t) Only the images from topic "topic" are used for the video output.')
    print('-v      Verbose messages are displayed.')
    print('--prefix (-p) set a output file name prefix othervise \'bagfile1\' is used (if -o is not set).')
    print('--start Optional start time in seconds.')
    print('--end   Optional end time in seconds.')
class RosVideoWriter():
    def __init__(self, fps=25.0, rate=1.0, topic="", output_filename ="", display= False, verbose = False, start = rospy.Time(0), end = rospy.Time(sys.maxsize)):
        self.opt_topic = topic
        self.opt_out_file = output_filename
        self.opt_verbose = verbose
        self.opt_display_images = display
        self.opt_start = start
        self.opt_end = end
        self.rate = rate
        self.fps = fps
        self.opt_prefix= None
        self.t_first={}
        self.t_file={}
        self.t_video={}
        self.p_avconv = {}
        
    #语法分析Args
    def parseArgs(self, args):
        opts, opt_files = getopt.getopt(args,"hsvr:o:t:p:",["fps=","rate=","ofile=","topic=","start=","end=","prefix="])
        #getopt()
        for opt, arg in opts:
            if opt == '-h':
                print_help()
                sys.exit(0)
            elif opt == '-s':
                self.opt_display_images = True
            elif opt == '-v':
                self.opt_verbose = True
            elif opt in ("--fps"):
                self.fps = float(arg)
            elif opt in ("-r", "--rate"):
                self.rate = float(arg)
            elif opt in ("-o", "--ofile"):
                self.opt_out_file = arg
            elif opt in ("-t", "--topic"):
                self.opt_topic = arg
            elif opt in ("-p", "--prefix"):
                self.opt_prefix = arg
            elif opt in ("--start"):
                self.opt_start = rospy.Time(int(arg))
                if(self.opt_verbose):
                    print("starting at",self.opt_start.to_sec())
            elif opt in ("--end"):
                self.opt_end = rospy.Time(int(arg))
                if(self.opt_verbose):
                    print("ending at",self.opt_end.to_sec())
            else:
                print("opt:", opt,'arg:', arg)
 
        if (self.fps<=0):
            print("invalid fps", self.fps)
            self.fps = 1
 
        if (self.rate<=0):
            print("invalid rate", self.rate)
            self.rate = 1
 
        if(self.opt_verbose):
            print("using ",self.fps," FPS")
        return opt_files
    # filter messages using type or only the opic we whant from the 'topic' argument
    def filter_image_msgs(self, topic, datatype, md5sum, msg_def, header):
        if(datatype=="sensor_msgs/CompressedImage"):
            if (self.opt_topic != "" and self.opt_topic == topic) or self.opt_topic == "":
                print("############# COMPRESSED IMAGE  ######################")
                print(topic,' with datatype:', str(datatype))
                print()
                return True;
 
        if(datatype=="theora_image_transport/Packet"):
            if (self.opt_topic != "" and self.opt_topic == topic) or self.opt_topic == "":
                print(topic,' with datatype:', str(datatype))
                print('!!! theora is not supported, sorry !!!')
                return False;
 
        if(datatype=="sensor_msgs/Image"):
            if (self.opt_topic != "" and self.opt_topic == topic) or self.opt_topic == "":
                print("############# UNCOMPRESSED IMAGE ######################")
                print(topic,' with datatype:', str(datatype))
                print()
                return True;
 
        return False;
    def write_output_video(self, msg, topic, t, video_fmt, pix_fmt = ""):
        # no data in this topic
        if len(msg.data) == 0 :
            return
        # initiate data for this topic
        if not topic in self.t_first :
            self.t_first[topic] = t # timestamp of first image for this topic
            self.t_video[topic] = 0
            self.t_file[topic] = 0
        # if multiple streams of images will start at different times the resulting video files will not be in sync
        # current offset time we are in the bag file
        self.t_file[topic] = (t-self.t_first[topic]).to_sec()
        # fill video file up with images until we reache the current offset from the beginning of the bag file
        while self.t_video[topic] < self.t_file[topic]/self.rate :
            if not topic in self.p_avconv:
                # we have to start a new process for this topic
                if self.opt_verbose :
                    print("Initializing pipe for topic", topic, "at time", t.to_sec())
                if self.opt_out_file=="":
                    out_file = self.opt_prefix + str(topic).replace("/", "_")+".mp4"
                else:
                    out_file = self.opt_out_file
 
                if self.opt_verbose :
                    print("Using output file ", out_file, " for topic ", topic, ".")
 
                if video_fmt == MJPEG_VIDEO :
                    cmd = [VIDEO_CONVERTER_TO_USE, '-v', '1', '-stats', '-r',str(self.fps),'-c','mjpeg','-f','mjpeg','-i','-','-an',out_file]
                    self.p_avconv[topic] = subprocess.Popen(cmd, stdin=subprocess.PIPE)
                    if self.opt_verbose :
                        print("Using command line:")
                        print(cmd)
                elif video_fmt == RAWIMAGE_VIDEO :
                    size = str(msg.width)+"x"+str(msg.height)
                    cmd = [VIDEO_CONVERTER_TO_USE, '-v', '1', '-stats','-r',str(self.fps),'-f','rawvideo','-s',size,'-pix_fmt', pix_fmt,'-i','-','-an',out_file]
                    self.p_avconv[topic] = subprocess.Popen(cmd, stdin=subprocess.PIPE)
                    if self.opt_verbose :
                        print("Using command line:")
                        print(cmd)
 
                else :
                    print("Script error, unknown value for argument video_fmt in function write_output_video.")
                    exit(1)
            # send data to ffmpeg process pipe
            self.p_avconv[topic].stdin.write(msg.data)
            # next frame time
            self.t_video[topic] += 1.0/self.fps
 
    def addBag(self, filename):
        if self.opt_display_images:
            from cv_bridge import CvBridge, CvBridgeError
            bridge = CvBridge()
            cv_image = []
 
        if self.opt_verbose :
            print("Bagfile: {}".format(filename))
 
        if not self.opt_prefix:
            # create the output in the same folder and name as the bag file minu '.bag'
            self.opt_prefix = bagfile[:-4]
 
        #Go through the bag file
        bag = rosbag.Bag(filename)
        if self.opt_verbose :
            print("Bag opened.")
        # loop over all topics
        for topic, msg, t in bag.read_messages(connection_filter=self.filter_image_msgs, start_time=self.opt_start, end_time=self.opt_end):
            try:
                if msg.format.find("jpeg")!=-1 :
                    if msg.format.find("8")!=-1 and (msg.format.find("rgb")!=-1 or msg.format.find("bgr")!=-1 or msg.format.find("bgra")!=-1 ):
                        if self.opt_display_images:
                            np_arr = np.fromstring(msg.data, np.uint8)
                            cv_image = cv2.imdecode(np_arr, cv2.CV_LOAD_IMAGE_COLOR)
                        self.write_output_video( msg, topic, t, MJPEG_VIDEO )
                    elif msg.format.find("mono8")!=-1 :
                        if self.opt_display_images:
                            np_arr = np.fromstring(msg.data, np.uint8)
                            cv_image = cv2.imdecode(np_arr, cv2.CV_LOAD_IMAGE_COLOR)
                        self.write_output_video( msg, topic, t, MJPEG_VIDEO )
                    elif msg.format.find("16UC1")!=-1 :
                        if self.opt_display_images:
                            np_arr = np.fromstring(msg.data, np.uint16)
                            cv_image = cv2.imdecode(np_arr, cv2.CV_LOAD_IMAGE_COLOR)
                        self.write_output_video( msg, topic, t, MJPEG_VIDEO )
                    else:
                        print('unsupported jpeg format:', msg.format, '.', topic)
 
            # has no attribute 'format'
            except AttributeError:
                try:
                        pix_fmt=None
                        if msg.encoding.find("mono8")!=-1 or msg.encoding.find("8UC1")!=-1:
                            pix_fmt = "gray"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
 
                        elif msg.encoding.find("bgra")!=-1 :
                            pix_fmt = "bgra"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
 
                        elif msg.encoding.find("bgr8")!=-1 :
                            pix_fmt = "bgr24"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
                        elif msg.encoding.find("bggr8")!=-1 :
                            pix_fmt = "bayer_bggr8"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bayer_bggr8")
                        elif msg.encoding.find("rggb8")!=-1 :
                            pix_fmt = "bayer_rggb8"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bayer_rggb8")
                        elif msg.encoding.find("rgb8")!=-1 :
                            pix_fmt = "rgb24"
                            if self.opt_display_images:
                                cv_image = bridge.imgmsg_to_cv2(msg, "bgr8")
                        elif msg.encoding.find("16UC1")!=-1 :
                            pix_fmt = "gray16le"
                        else:
                            print('unsupported encoding:', msg.encoding, topic)
                            #exit(1)
                        if pix_fmt:
                            self.write_output_video( msg, topic, t, RAWIMAGE_VIDEO, pix_fmt )
 
                except AttributeError:
                    # maybe theora packet
                    # theora not supported
                    if self.opt_verbose :
                        print("Could not handle this format. Maybe thoera packet? theora is not supported.")
                    pass
            if self.opt_display_images:
                cv2.imshow(topic, cv_image)
                key=cv2.waiTKEy(1)
                if key==1048603:
                    exit(1)
        if self.p_avconv == {}:
            print("No image topics found in bag:", filename)
        bag.close()
if __name__ == '__main__':
    #print()
    #print('rosbag2video, by Maximilian Laiacker 2020 and Abel Gabor 2019')
    #print()
 
    if len(sys.argv) < 2:
        print('Please specify ros bag file(s)!')
        print_help()
        sys.exit(1)
    else :
        videowriter = RosVideoWriter()
        try:
            opt_files = videowriter.parseArgs(sys.argv[1:])
        except getopt.GetoptError:
            print_help()
            sys.exit(2)
    # loop over all files
    for files in range(0,len(opt_files)):
        #First arg is the bag to look at
        bagfile = opt_files[files]
        videowriter.addBag(bagfile)
    print("finished")

main.py

import glob
import sys
import glob
import os
import argparse

def mkdir(path):
    if not os.path.exists(path):
        os.mkdir(path)
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='''This is a code for bag2video.''')
    parser.add_argument('--data_root', type=str, default=r'/test/data', help='path to the root of data')
    parser.add_argument('--out_root', type=str, default=r'/test/save', help='path to the root of data')
    parser.add_argument('--fps', type=int, default=25, help='path to the root of data')
    args = parser.parse_args()

    mkdir(args.out_root)
    bagList = glob.glob(os.path.join(args.data_root, "*.bag"))
    for bagPath in bagList:
        baseName = os.path.basename(bagPath).split(".")[0]
        outPath = os.path.join(args.out_root, baseName + ".mp4")
        os.system("python bag2video.py -o {outName} --fps {fps} {bagPath}".format(outName=outPath, fps=args.fps, bagPath=bagPath))

到此这篇关于如何将bag文件批量转成mp4的文章就介绍到这了,更多相关bag文件批量转成mp4内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何将bag文件批量转成mp4

本文链接: https://www.lsjlt.com/news/120702.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何将bag文件批量转成mp4
    目录简介dockerfileBuild docker imageBuild docker containerRun scriptSource codebag2video.pymain...
    99+
    2022-11-11
  • Python怎么批量将csv文件转化成xml文件
    这篇文章主要介绍了Python怎么批量将csv文件转化成xml文件,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。python主要应用领域有哪些1、云计算,典型应用OpenSt...
    99+
    2023-06-15
  • Python批量将csv文件转化成xml文件的实例
    一、前言 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须...
    99+
    2022-06-02
    Python csv转xml python csv文件转换
  • python小脚本——批量将PDF文件转换成图片
    语言:python 3 用法:选择PDF文件所在的目录,点击 确定 后,自动将该目录下的所有PDF转换成单个图片,图片名称为:   pdf文件名.page_序号.jpg 如运行中报错,需要自行根据报错内容按照缺失的库 例如: #安装库pip...
    99+
    2023-09-10
    python
  • Win7系统如何将qsv文件转换为mp4
    由于qsv文件是爱奇艺特有的视频格式,不被许多播放器支持,因此我们需要进行格式转换。如何将qsv文件转换为mp4,实际上非常简单,如果您不明白,那就赶紧看看小编整理的Win7系统的qsv文件转化为mp4吧!将qsv转换为flv的方法:首先下...
    99+
    2023-07-18
  • 哔哩哔哩缓存转码|FFmpeg将m4s文件转为mp4|PHP自动批量转码B站视频
    window下载安装FFmpeg 打开ffMpeg官网选择window=>Windows builds from gyan.dev 打开https://www.gyan.dev/ffmpeg/buil...
    99+
    2023-08-31
    ffmpeg php 音视频
  • 如何利用Python代码批量将PDF文件转为Word格式
    本篇文章给大家分享的是有关如何利用Python代码批量将PDF文件转为Word格式,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在日常工作或学习中,经常会遇到这样的无奈:“小任...
    99+
    2023-06-17
  • windows CR2格式文件如何批量转换成JPG等格式
    本文小编为大家详细介绍“windows CR2格式文件如何批量转换成JPG等格式”,内容详细,步骤清晰,细节处理妥当,希望这篇“windows CR2格式文件如何批量转换成JPG等格式”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-07-01
  • php如何将word文档转成PDF文件
    本文小编为大家详细介绍“php如何将word文档转成PDF文件”,内容详细,步骤清晰,细节处理妥当,希望这篇“php如何将word文档转成PDF文件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。第一步:安装和配置...
    99+
    2023-07-05
  • 如何将HTML文件转换成Word文档
    随着互联网和信息技术的不断进步,越来越多的人开始使用网页来展示和传递信息。然而,有些情况下我们需要将网页的内容转换成Word文档,例如需要打印文档、需要在Word中编辑等。本文将介绍如何将HTML文件转换成Word文档。一、使用在线转换工具...
    99+
    2023-05-14
  • 报表如何批量导出成 excel 文件
    需求说明报表展现后可以通过工具栏中的导出按钮将当前展现的报表导出成 excel 文件,但是在实际使用中通常会要求报表不需要展现,直接通过一些操作将报表导出成 excel 文件,并且往往会要求批量导出成 excel 文件,下面通过几个示例介绍...
    99+
    2023-06-02
  • 如何将文件流转换成byte[]数组
    目录将文件流转换成byte[]数组将文件转为byte[],通过ByteArrayOutputStream实现通过文件路径转换byte[]将bitmap对象将文件流转换成byte[]数...
    99+
    2022-11-12
  • VB.NET中如何将图像转成HTML文件
    这篇文章主要为大家展示了“VB.NET中如何将图像转成HTML文件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“VB.NET中如何将图像转成HTML文件”这篇文章吧。在vb.net中写出了相同实...
    99+
    2023-06-17
  • Linux下如何将文本文档转换成PDF文件
    这篇文章将为大家详细讲解有关Linux下如何将文本文档转换成PDF文件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。现在有很多软件能够将文本文件转换成PDF文件,其实在Linux系统中,不用使用软件也能将...
    99+
    2023-06-27
  • 如何用phpexcel将Excel文件转成CSV文件并打开
    这篇“如何用phpexcel将Excel文件转成CSV文件并打开”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何用phpe...
    99+
    2023-07-05
  • php如何实现批量转成utf-8
    这篇文章主要讲解了“php如何实现批量转成utf-8”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php如何实现批量转成utf-8”吧!php实现批量转成utf-8的方法:1、创建一个PHP...
    99+
    2023-06-28
  • php如何将变量转换成float
    这篇文章主要为大家展示了“php如何将变量转换成float”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“php如何将变量转换成float”这篇文章吧。方法:1、在变量或值前添加“(float)”...
    99+
    2023-06-15
  • 如何使用Python批量对文本文件编码互转
    本文小编为大家详细介绍“如何使用Python批量对文本文件编码互转”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用Python批量对文本文件编码互转”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在Wind...
    99+
    2023-07-05
  • php如何将中文转成byte
    这篇文章给大家分享的是有关php如何将中文转成byte的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php将中文转成byte的方法:1、创建一个PHP示例文件;2、通过“function stringToByte...
    99+
    2023-06-25
  • python如何批量将PPT导出成图片集
    本篇内容主要讲解“python如何批量将PPT导出成图片集”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python如何批量将PPT导出成图片集”吧!导读需要使用python做一个将很多个不规则...
    99+
    2023-06-07
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作