ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

how to recover the saved images in a bagfile to jpg or png

asked 2012-02-15 10:47:34 -0500

Eddit gravatar image

I have a bag file with image sensor message how I can recover and save the images into the jpg or png files?

I appreciate your help.

edit retag flag offensive close merge delete

5 Answers

Sort by ยป oldest newest most voted
6

answered 2012-02-15 11:30:45 -0500

imcmahon gravatar image

updated 2016-09-06 21:18:37 -0500

EDIT: This answer was applicable back in the ROS Fuerte days of rosmake. I'd recommend checking out one of the other answers for any modern ROS version.

ORIGINAL: I've successfully used this tutorial in the past to extract images / video from .bag files:

http://www.ros.org/wiki/rosbag/Tutori...

Good luck!

edit flag offensive delete link more

Comments

In the example the bag file should be in a ros folder. Is it possible to locate the bag file in not ros folder and have the launch file in the same folder and find the bag file ?

Eddit gravatar image Eddit  ( 2012-02-15 12:03:46 -0500 )edit
2

Instead of $(find image_view)/test.bag you should be able to put a hard-coded absolute path to your bag file. I haven't tested that.

Thomas D gravatar image Thomas D  ( 2012-02-15 13:02:29 -0500 )edit

Is there an option for png images?

2ROS0 gravatar image 2ROS0  ( 2016-09-02 15:35:34 -0500 )edit
6

answered 2012-02-15 11:34:12 -0500

Thomas D gravatar image

updated 2020-11-23 10:16:17 -0500

lucasw gravatar image

I use the Python script below as a ROS node to convert a bag file to a set of images in a directory. To run I use:

rosrun my_package bag_to_images.py ../saved_images ../input.bag

where the saved_images/ directory must exist beforehand. Also, give the location of saved_images/ relative to the directory where the bag_to_images.py script is located. The input.bag file should also be specified relative to the directory where the bag_to_images.py script is located. It is possible to use this in a launch file but I never do that.

For each image topic just put another if topic == section into the script and modify the topic names to match those in your bag file. The images get saved to saved_images/right_{message timestamp}.pgm. To save as .png or .jpg just change those lines to use those file extensions, as OpenCV is smart enough to figure out how to write the files the correct way. See here at the cv::imread section for supported formats with OpenCV.

#!/usr/bin/python

# Start up ROS pieces.
PKG = 'my_package'
import roslib; roslib.load_manifest(PKG)
import rosbag
import rospy
import cv
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

# Reading bag filename from command line or roslaunch parameter.
import os
import sys

class ImageCreator():
    # Must have __init__(self) function for a class, similar to a C++ class constructor.
    def __init__(self):
        # Get parameters when starting node from a launch file.
        if len(sys.argv) < 1:
            save_dir = rospy.get_param('save_dir')
            filename = rospy.get_param('filename')
            rospy.loginfo("Bag filename = %s", filename)
        # Get parameters as arguments to 'rosrun my_package bag_to_images.py <save_dir> <filename>', where save_dir and filename exist relative to this executable file.
        else:
            save_dir = os.path.join(sys.path[0], sys.argv[1])
            filename = os.path.join(sys.path[0], sys.argv[2])
            rospy.loginfo("Bag filename = %s", filename)

        # Use a CvBridge to convert ROS images to OpenCV images so they can be saved.
        self.bridge = CvBridge()

        # Open bag file.
        with rosbag.Bag(filename, 'r') as bag:
            for topic, msg, t in bag.read_messages():
                if topic == "/left/image_raw":
                    try:
                        cv_image = self.bridge.imgmsg_to_cv(msg, "bgr8")
                    except CvBridgeError, e:
                        print(e)
                    timestr = "%.6f" % msg.header.stamp.to_sec()
                    image_name = str(save_dir)+"/left_"+timestr+".pgm"
                    #image_name = str(save_dir)+"/"+timestr+"_left"+".pgm"
                    cv.SaveImage(image_name, cv_image)
                if topic == "/right/image_raw":
                    try:
                        cv_image = self.bridge.imgmsg_to_cv(msg, "bgr8")
                    except CvBridgeError, e:
                        print(e)
                    timestr = "%.6f" % msg.header.stamp.to_sec()
                    image_name = str(save_dir)+"/right_"+timestr+".pgm"
                    #image_name = str(save_dir)+"/"+timestr+"_right"+".pgm"
                    cv.SaveImage(image_name, cv_image)

# Main function.    
if __name__ == '__main__':
    # Initialize the node and name it.
    rospy.init_node(PKG)
    # Go to class functions that do all the heavy lifting. Do error checking.
    try:
        image_creator = ImageCreator()
    except rospy.ROSInterruptException: pass
edit flag offensive delete link more

Comments

I am confused between using header timestamp and normal timestamp. Would the file name have the timestamp when the image was captured or when the image was recorded. If it is the recorded one, can we change it to the time when it was captured or we need to publish another clock topic and then map.

3XTR3M3 gravatar image 3XTR3M3  ( 2018-03-20 13:04:37 -0500 )edit

I don't know what you mean by the difference between captured and recorded. However, the image messages in the bag will have a header that has the timestamp of when the message was published. That published time will be the time used when generating the filename.

Thomas D gravatar image Thomas D  ( 2018-03-21 07:35:32 -0500 )edit
1

answered 2016-02-02 02:44:14 -0500

Tommi gravatar image

updated 2020-11-23 10:16:44 -0500

lucasw gravatar image

I modified Thomas D's answer for OpenCV version 2.

* All topics that contain a search term (desired_topic) are accepted.
* Option to include image index with leading zeroes (index_in_filename)
* Delimiter changed to '-' to avoid confusion with underscores in topic names.
* Support for compressed topics.

Code:

#!/usr/bin/python

# Extract images from a bag file.
#
# Original author: Thomas Denewiler (http://answers.ros.org/users/304/thomas-d/)

# Start up ROS pieces.
PKG = 'my_package'
import roslib; roslib.load_manifest(PKG)
import rosbag
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

# Reading bag filename from command line or roslaunch parameter.
import os
import sys

class ImageCreator():

    image_type = ".jpg"
    desired_topic = "image_raw"
    index_in_filename = True
    index_format = "06d"
    image_index = 0

    # Must have __init__(self) function for a class, similar to a C++ class constructor.
    def __init__(self):
        # Get parameters when starting node from a launch file.
        if len(sys.argv) < 1:
            save_dir = rospy.get_param('save_dir')
            filename = rospy.get_param('filename')
            rospy.loginfo("Bag filename = %s", filename)
        # Get parameters as arguments to 'rosrun my_package bag_to_images.py <save_dir> <filename>', where save_dir and filename exist relative to this executable file.
        else:
            save_dir = os.path.join(sys.path[0], sys.argv[1])
            filename = os.path.join(sys.path[0], sys.argv[2])
            rospy.loginfo("Bag filename = %s", filename)

        # Use a CvBridge to convert ROS images to OpenCV images so they can be saved.
        self.bridge = CvBridge()

        # Open bag file.
        with rosbag.Bag(filename, 'r') as bag:
            for topic, msg, t in bag.read_messages():
                topic_parts = topic.split('/')
                # first part is empty string
                if len(topic_parts) == 3 and topic_parts[2] == self.desired_topic:
                    try:
                        cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
                    except CvBridgeError, e:
                        print(e)
                    timestr = "%.3f" % msg.header.stamp.to_sec()
                    if self.index_in_filename:
                        image_name = str(save_dir) + "/" + topic_parts[1] + "-" + format(self.image_index, self.index_format) + "-" + timestr + self.image_type
                    else:
                        image_name = str(save_dir) + "/" + topic_parts[1] + "-" + timestr + self.image_type
                    cv2.imwrite(image_name, cv_image)
                    self.image_index = self.image_index + 1

# Main function.    
if __name__ == '__main__':
    # Initialize the node and name it.
    rospy.init_node(PKG)
    # Go to class functions that do all the heavy lifting. Do error checking.
    try:
        image_creator = ImageCreator()
    except rospy.ROSInterruptException: pass
edit flag offensive delete link more
1

answered 2017-04-15 02:15:44 -0500

Gourav_Kumar gravatar image

The easiest way I found was using "image_saver" tool of "image_view" package through the terminal. More details can be found at : http://wiki.ros.org/image_view .

example: Play the *.bag file and use "rosrun image_view image_saver image:=[your topic]"

similarly "video_recorder" tool can be used for extracting video.

edit flag offensive delete link more
-1

answered 2012-02-15 22:36:36 -0500

liquidmonkey gravatar image

have you tried bag_to_pcd? then you can use pcd_viewer and take a screenshot which is saved as a png file.

http://www.ros.org/wiki/pcl_ros#bag_to_pcd

and you need to edit the code a bit but its explained here: http://www.pcl-users.org/conversion-bag-to-pcd-td2770573.html

edit flag offensive delete link more

Question Tools

Stats

Asked: 2012-02-15 10:47:34 -0500

Seen: 16,840 times

Last updated: Nov 23 '20