rosbagファイルからjpegを抽出する方法
目的
分割されたrosbagファイルから、対象のセンサノード(ここでは受光センサ)の全フレームをjpegとして出力する
なおファイル名はフレーム番号の他、受信時間(ナノ秒)も付与する
環境
-
Ubuntu 18.04.2 LTS
https://www.ubuntulinux.jp/download/ja-remix -
ROS Melodic
http://wiki.ros.org/melodic/Installation/Ubuntu
方法
- UbuntuにROS Medlodicをインストールする
- 下記のようなpythonコードを用意する
#! /usr/bin/python
import os
import sys
import cv2
import csv
import rospy, rosbag
import numpy as np
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
if len(sys.argv) == 3:
sys.argv[1] = sys.argv[1] + ".dir"
out_dir = sys.argv[1]
if not os.path.exists(sys.argv[1]):
os.makedirs(out_dir)
else:
print sys.argv[1], 'already exists'
sys.exit()
bagfile = sys.argv[2]
else:
print 'illegal arguments exeption.'
sys.exit()
bridge = CvBridge()
def main():
topicNames = {'/front_camera/image_color/compressed'
, '/rear_camera/image_color/compressed'}
inbag_name = bagfile
print "open rosbag file..."
bag = rosbag.Bag(inbag_name)
for topic, msg, t in bag.read_messages():
if topic in topicNames:
try:
img = bridge.compressed_imgmsg_to_cv2(msg)
except CvBridgeError, e:
print(e)
else:
filename = '/' + str(msg.header.seq) + '_' + str(msg.header.stamp) + '_' + topic.split('/')[1].replace('_', '-') + '.jpg'
cv2.imwrite(sys.argv[1] + filename, img)
with open(sys.argv[1]+'/metadata.csv','ab') as f:
thewriter = csv.writer(f)
thewriter.writerow([str(msg.header.seq),str(msg.header.stamp),os.getcwd()+'/'+sys.argv[1]+'/', filename])
bag.close()
if __name__ == "__main__":
main()
PythonでなくともC++でも可能だが環境を作るのが面倒だったのでここではpythonを使用している
またROSはpython2のみサポートしているようだ
他の方法としてROS Medlodicに付属してくるrosbagの標準コマンドを使用する方法もあるがリアルタイムシミュレートのためか環境によってはフレームが欠落するので今回は見送った
またこいつは連番しか付与できないのでタイムスタンプが出力できないことにも注意
3. 下記のようなコマンドで一括で実行する
find -name "*.rosbag" | xargs -I@ sh -c "python2 ~/tmp/__main__.py @ @"
結果
全フレームがjpegで出力される
ただし複数カメラなどで、あるカメラを基準に最も近いほかカメラのフレームを取得したい場合(フレームを同期したい)にはこれでは不十分である
それを解決したスクリプトもあるのだが、需要があればまた今後どこかでまとめたい