以下兩種環境均在Ubuntu16.04環境下測試成功。
第一種方法
ROS-從rosbag中提取圖像(by launch文件)
1.新建launch文件(文件在哪無所謂,可以在catkin_ws的根目錄) : bag2img.launch
<launch>
<node pkg="rosbag" type="play" name="rosbag" args="-d 2 /home/andy/bag_foler/file_name.bag"/>
<node name="extract" pkg="image_view" type="extract_images" respawn="false" output="screen" cwd="ROS_HOME">
<remap from="image" to="camera/rgb/image_color"/>
<param name="sec_per_frame" value="0.03"/>
</node>
</launch>
note:
/home/andy/bag_foler/file_name.bag
爲你錄製的bag文件的絕對路徑,camera/rgb/image_color
爲你提取的topic的名字,你可以使用:
rosbag info file_name.bag
查看你需要提取的圖片的topic名字。< param name="sec_per_frame" value="0.03"/>
這句話是說,以每一幀花費0.03s的時間,這個條件對你的bag文件進行圖像提取,如果沒有這句話,就是默認0.1s,也就是沒秒10幀的速率對圖像提取。經過我的測試發現,無論怎麼調整這個值,都無法跟bag文件中的信息數目匹配,因此來說,這種方法存在一定的圖像缺失的情況,只能無限接近袁原始圖像的數目,比如我的原始數據有640幀,但經過調整sec_per_frame的值,最高的時候還是隻能到639,多數情況下到637,默認值0.1的時候,只有200多張圖像。
2.運行launch
roslaunch bag2img.launch
那麼已經提取成功的圖像存儲在你home文件夾下的.ros文件夾下,一般是隱藏的文件夾,使用crtl+h可顯示出來。
優點:操作簡單,使用ros即可;缺點:提取信息與原始錄製的信息並不完全一致,主要體現在提取的圖片數量和ros錄製的時候的信息數量不一致,會少。此外,不含有時間戳;
第二種方法
ROS-從rosbag中提取圖像(by python2)
通過編寫Python程序按照我們想要的信息及方式來提取,在與bag文件同級目錄下建立.py文件(方便操作,若不是同級目錄,下面代碼中要寫絕對路徑)
# coding:utf-8
#!/usr/bin/python
# Extract images from a bag file.
#PKG = 'beginner_tutorials'
import roslib; #roslib.load_manifest(PKG)
import rosbag
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError
# Reading bag filename from command line or roslaunch parameter.
#import os
#import sys
rgb_path = '/home/david/workspace/bags/rgb/' #已經建立好的存儲rgb彩色圖文件的目錄
depth_path= '/home/david/workspace/bags/depth/' # 已經建立好的存儲深度圖文件的目錄
class ImageCreator():
def __init__(self):
self.bridge = CvBridge()
with rosbag.Bag('/home/andy/bag_folder/file_name.bag', 'r') as bag: #要讀取的bag文件;
for topic,msg,t in bag.read_messages():
if topic == "camera/rgb/image_raw": #圖像的topic;
try:
cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")
except CvBridgeError as e:
print e
timestr = "%.6f" % msg.header.stamp.to_sec()
#%.6f表示小數點後帶有6位,可根據精確度需要修改;
image_name = timestr+ ".png" #圖像命名:時間戳.png
cv2.imwrite(rgb_path + image_name, cv_image) #保存;
elif topic == "camera/depth_registered/image_raw": #圖像的topic;
try:
cv_image = self.bridge.imgmsg_to_cv2(msg,"16UC1")
except CvBridgeError as e:
print e
timestr = "%.6f" % msg.header.stamp.to_sec()
#%.6f表示小數點後帶有6位,可根據精確度需要修改;
image_name = timestr+ ".png" #圖像命名:時間戳.png
cv2.imwrite(depth_path + image_name, cv_image) #保存;
if __name__ == '__main__':
#rospy.init_node(PKG)
try:
image_creator = ImageCreator()
except rospy.ROSInterruptException:
pass