|
| 1 | +#!/usr/bin/python |
| 2 | +""" |
| 3 | +Created from image_sequence_publisher.py |
| 4 | +Mathieu Labbe |
| 5 | +
|
| 6 | +Copyright (c) 2012, |
| 7 | +Systems, Robotics and Vision Group |
| 8 | +University of the Balearican Islands |
| 9 | +All rights reserved. |
| 10 | +
|
| 11 | +Redistribution and use in source and binary forms, with or without |
| 12 | +modification, are permitted provided that the following conditions are met: |
| 13 | + * Redistributions of source code must retain the above copyright |
| 14 | + notice, this list of conditions and the following disclaimer. |
| 15 | + * Redistributions in binary form must reproduce the above copyright |
| 16 | + notice, this list of conditions and the following disclaimer in the |
| 17 | + documentation and/or other materials provided with the distribution. |
| 18 | + * Neither the name of Systems, Robotics and Vision Group, University of |
| 19 | + the Balearican Islands nor the names of its contributors may be used to |
| 20 | + endorse or promote products derived from this software without specific |
| 21 | + prior written permission. |
| 22 | +
|
| 23 | +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 24 | +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 25 | +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 26 | +DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY |
| 27 | +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 28 | +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 29 | +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 30 | +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 31 | +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 32 | +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 33 | +""" |
| 34 | + |
| 35 | + |
| 36 | +PKG = 'bag_tools' # this package name |
| 37 | + |
| 38 | +import roslib; roslib.load_manifest(PKG) |
| 39 | +import rospy |
| 40 | +import sensor_msgs.msg |
| 41 | +import cv_bridge |
| 42 | +import camera_info_parser |
| 43 | +import glob |
| 44 | +import cv |
| 45 | +import numpy as np |
| 46 | +import re |
| 47 | + |
| 48 | +def natural_sort(l): |
| 49 | + convert = lambda text: int(text) if text.isdigit() else text.lower() |
| 50 | + alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] |
| 51 | + return sorted(l, key = alphanum_key) |
| 52 | + |
| 53 | +def collect_image_files(image_dir,file_pattern): |
| 54 | + images = glob.glob(image_dir + '/' + file_pattern) |
| 55 | + images = natural_sort(images) |
| 56 | + return images |
| 57 | + |
| 58 | +def playback_images(image_dir_l, image_dir_r, file_pattern, camera_info_file_l, camera_info_file_r, publish_rate): |
| 59 | + if camera_info_file_l != "": |
| 60 | + cam_info_l = camera_info_parser.parse_yaml(camera_info_file_l) |
| 61 | + publish_cam_info_l = True |
| 62 | + else: |
| 63 | + publish_cam_info_l = False |
| 64 | + if camera_info_file_r != "": |
| 65 | + cam_info_r = camera_info_parser.parse_yaml(camera_info_file_r) |
| 66 | + publish_cam_info_r = True |
| 67 | + else: |
| 68 | + publish_cam_info_r = False |
| 69 | + |
| 70 | + image_files_l = collect_image_files(image_dir_l, file_pattern) |
| 71 | + image_files_r = collect_image_files(image_dir_r, file_pattern) |
| 72 | + rospy.loginfo('Found %i left images.',len(image_files_l)) |
| 73 | + rospy.loginfo('Found %i right images.',len(image_files_r)) |
| 74 | + |
| 75 | + bridge = cv_bridge.CvBridge() |
| 76 | + rate = rospy.Rate(publish_rate) |
| 77 | + image_publisher_l = rospy.Publisher('stereo_camera/left/image_color', sensor_msgs.msg.Image, queue_size = 1) |
| 78 | + image_publisher_r = rospy.Publisher('stereo_camera/right/image_color', sensor_msgs.msg.Image, queue_size = 1) |
| 79 | + if publish_cam_info_l: |
| 80 | + cam_info_publisher_l = rospy.Publisher('stereo_camera/left/camera_info', sensor_msgs.msg.CameraInfo, queue_size = 1) |
| 81 | + if publish_cam_info_r: |
| 82 | + cam_info_publisher_r = rospy.Publisher('stereo_camera/right/camera_info', sensor_msgs.msg.CameraInfo, queue_size = 1) |
| 83 | + |
| 84 | + rospy.loginfo('Starting playback.') |
| 85 | + for image_file_l, image_file_r in zip(image_files_l, image_files_r): |
| 86 | + if rospy.is_shutdown(): |
| 87 | + break |
| 88 | + now = rospy.Time.now() |
| 89 | + image_l = cv.LoadImage(image_file_l) |
| 90 | + image_r = cv.LoadImage(image_file_r) |
| 91 | + image_msg = bridge.cv2_to_imgmsg(np.asarray(image_l[:,:]), encoding='bgr8') |
| 92 | + image_msg.header.stamp = now |
| 93 | + image_msg.header.frame_id = "/camera" |
| 94 | + image_publisher_l.publish(image_msg) |
| 95 | + image_msg = bridge.cv2_to_imgmsg(np.asarray(image_r[:,:]), encoding='bgr8') |
| 96 | + image_msg.header.stamp = now |
| 97 | + image_msg.header.frame_id = "/camera" |
| 98 | + image_publisher_r.publish(image_msg) |
| 99 | + if publish_cam_info_l: |
| 100 | + cam_info_l.header.stamp = now |
| 101 | + cam_info_l.header.frame_id = "/camera" |
| 102 | + cam_info_publisher_l.publish(cam_info_l) |
| 103 | + if publish_cam_info_r: |
| 104 | + cam_info_r.header.stamp = now |
| 105 | + cam_info_r.header.frame_id = "/camera" |
| 106 | + cam_info_publisher_r.publish(cam_info_r) |
| 107 | + rate.sleep() |
| 108 | + rospy.loginfo('No more images left. Stopping.') |
| 109 | + |
| 110 | +if __name__ == "__main__": |
| 111 | + rospy.init_node('image_sequence_publisher') |
| 112 | + try: |
| 113 | + image_dir_l = rospy.get_param("~image_dir_left") |
| 114 | + image_dir_r = rospy.get_param("~image_dir_right") |
| 115 | + file_pattern = rospy.get_param("~file_pattern") |
| 116 | + camera_info_file_l = rospy.get_param("~camera_info_file_left", "") |
| 117 | + camera_info_file_r = rospy.get_param("~camera_info_file_right", "") |
| 118 | + frequency = rospy.get_param("~frequency", 10) |
| 119 | + playback_images(image_dir_l, image_dir_r, file_pattern, camera_info_file_l, camera_info_file_r, frequency) |
| 120 | + except KeyError as e: |
| 121 | + rospy.logerr('Required parameter missing: %s', e) |
| 122 | + except Exception, e: |
| 123 | + import traceback |
| 124 | + traceback.print_exc() |
0 commit comments