ROS相机雷达数据采集并提取
一、采集数据
1、开车
开启底盘电源,松开急停
开启电池电源,分流电源,工控机开关
链接键盘,显示器,鼠标
2、开驱动
(以工控机为例,使用前都需要source)
水星相机驱动:roslaunch galaxy_camera ME3-132GC_xxx.launch
RS16线激光雷达驱动:roslaunch rslidar_sdk start.launch
rosbag record /话题 /话题
查看录包信息前,需要把雷达和相机的网线拔掉,以免冲突。
二、数据处理
1、提取雷达和相机
包位于/media/xxx/Elements/Data/Reality/save_camera_lidar/src/save_camera_lidar
话题名称查看rostopic list:
/clock /galaxy_camera/image_raw /rosout /rosout_agg /rslidar_points_16
类型查看:rostopic info /
相机与雷达外参:
RT.at<double>(0,0) = -0.064550; RT.at<double>(0,1) = -0.997901; RT.at<double>(0,2) = -0.005232; RT.at<double>(0,3) = 0.452897;
RT.at<double>(1,0) = 0.027399; RT.at<double>(1,1) = 0.003468; RT.at<double>(1,2) = -0.999619; RT.at<double>(1,3) = -9.681164;
RT.at<double>(2,0) = 0.997538; RT.at<double>(2,1) = -0.064669; RT.at<double>(2,2) = 0.027118; RT.at<double>(2,3) = -2.978566;
RT.at<double>(3,0) = 0.0; RT.at<double>(3,1) = 0.0; RT.at<double>(3,2) = 0.0; RT.at<double>(3,3) = 1.0;
相机内参:
P_rect_00.at<double>(0,0) = 1697.098875; P_rect_00.at<double>(0,1) = 0.810076; P_rect_00.at<double>(0,2) = 1205.070736; P_rect_00.at<double>(0,3) = 0.000000e+00;
P_rect_00.at<double>(1,0) = 0.000000e+00; P_rect_00.at<double>(1,1) = 1701.757828; P_rect_00.at<double>(1,2) = 991.242630; P_rect_00.at<double>(1,3) = 0.000000e+00;
P_rect_00.at<double>(2,0) = 0.000000e+00; P_rect_00.at<double>(2,1) = 0.000000e+00; P_rect_00.at<double>(2,2) = 1.000000e+00; P_rect_00.at<double>(2,3) = 0.000000e+00;
2、程序运行
bag位于Data/Reality
方法1
(Data/Reality/save_camera_lidar):源程序不动,修改bag路径和截取图像的时机,改成一接到图片就同时保存雷达点云和图片。
但是这样处理,掉帧爆炸。
方法2:
直接用自带程序提取:
执行$ rosrun image_view extract_images _sec_per_frame:=0.05 image:=/stereo/left/image_raw# <IMAGETOPICINBAGFILE>为bag文件中储存图片的topic
$ rosbag play <BAGFILE> # <BAGFILE>为bag文件的路径
然后就成功保存为jpg,mogrify -format png *.jpg转化成Png
雷达保存:
rosrun pcl_ros bag_to_pcd ulnc-ex.bag \lidar_cloud_calibrated lidar
这种保存方式图片掉很多帧。
方法3
利用参考程序提取https://www.it610.com/article/1291575475952492544.htm
报错ImportError: dynamic module does not define module export function (PyInit_cv_bridge_boost)
这里是因为cv_bridge只能在python2运行,必须要使用python2 xxx来运行。
然后就可以保存png结尾的数据。
方法3成功,程序位于media\Data\Reality\321\raw
附录:
PYTHON提取ROSBAG数据代码,需要在python2下运行
save_rosbag.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 os from sensor_msgs.msg import Image from cv_bridge import CvBridge from cv_bridge import CvBridgeError import sys sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages') import cv2 # Reading bag filename from command line or roslaunch parameter. #import os #import sys rgb_path = './image_0/' laser_path= './lidar' class ImageCreator(): def __init__(self): self.bridge = CvBridge() with rosbag.Bag('energy.bag', 'r') as bag: #要读取的bag文件; for topic,msg,t in bag.read_messages(): if topic == "/galaxy_camera/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 == "/rslidar_points_16": #laser的topic; timestr = "%.6f" % msg.header.stamp.to_sec() laser_data_name = timestr + ".txt" laser_data_path = os.path.join(laser_path, laser_data_name) with open(laser_data_path, "w") as f: f.write(str(msg)) if __name__ == '__main__': try: image_creator = ImageCreator() except rospy.ROSInterruptException: pass