imagevideo-streamingrosbag

How do I convert a video or a sequence of images to a bag file?


I am new to ROS. I need to convert a preexisting video file, or a large amount of images that can be concatenated into a video stream, into a .bag file in ROS. I found this code online: http://answers.ros.org/question/11537/creating-a-bag-file-out-of-a-image-sequence/, but it says it is for camera calibration, so not sure if it fits my purpose.

Could someone with a good knowledge of ROS confirm that I can use the code in the link provided for my purposes, or if anyone actually has the code I'm looking for, could you please post it here?


Solution

  • The following code converts a video file to a bag file, inspired from the code in the link provided.

    Little reminder:

    1. this code depends on cv2 (opencv python)

    2. time stamp of ROS message is calculated by frame index and fps. fps will be set to 24 if opencv unable to read it from the video.

    import time, sys, os
    from ros import rosbag
    import roslib, rospy
    roslib.load_manifest('sensor_msgs')
    from sensor_msgs.msg import Image
    
    from cv_bridge import CvBridge
    import cv2
    
    TOPIC = 'camera/image_raw/compressed'
    
    def CreateVideoBag(videopath, bagname):
        '''Creates a bag file with a video file'''
        bag = rosbag.Bag(bagname, 'w')
        cap = cv2.VideoCapture(videopath)
        cb = CvBridge()
        prop_fps = cap.get(cv2.CAP_PROP_FPS)
        if prop_fps != prop_fps or prop_fps <= 1e-2:
            print "Warning: can't get FPS. Assuming 24."
            prop_fps = 24
        ret = True
        frame_id = 0
        while(ret):
            ret, frame = cap.read()
            if not ret:
                break
            stamp = rospy.rostime.Time.from_sec(float(frame_id) / prop_fps)
            frame_id += 1
            image = cb.cv2_to_compressed_imgmsg(frame)
            image.header.stamp = stamp
            image.header.frame_id = "camera"
            bag.write(TOPIC, image, stamp)
        cap.release()
        bag.close()
    
    
    if __name__ == "__main__":
        if len( sys.argv ) == 3:
            CreateVideoBag(*sys.argv[1:])
        else:
            print( "Usage: video2bag videofilename bagfilename")