跑SLAM经常要用到各种数据库,以及ROS。以EuRoC数据库为例,其bag文件中存放了完整的话题信息,包括图像。昨天学习了一下2种从数据库中提取图像的方法,在此总结之。
1. 从bag文件中提取
首先查看bag文件中的msg数据格式,利用rosbag info
rosbag info ${Your path}/MH_01_easy.bag
然后创建launch文件,export.launch,可参见博客。
<launch>
<node pkg="rosbag" type="play" name="rosbag" args="-d 2 ${Your path}/MH_01_easy.bag"/>
<node name="extract" pkg="image_view" type="extract_images" respawn="false" output="screen" cwd="ROS_HOME">
<remap from="image" to="/cam0/image_raw"/>
</node>
</launch>
然后运行launch文件
source devel/setup.bash
roslaunch beginner_tutorials export.launch
所提取的图片在~/.ros
路径下,将其移到你的目标文件中即可查看图像。
2. 通过节点订阅并显示
需要回放bag数据,然后编写一个节点订阅其中的话题,然后显示,要用到cv_bridge和OpenCv,首先查看bag的话题,打开一个新的终端,输入
rosbag info ${Your path}/MH_01_easy.bag
显示:
compression: none [2456/2456 chunks]
types: geometry_msgs/PointStamped [c63aecb41bfdfd6b7e1fac37c7cbe7bf]
sensor_msgs/Image [060021388200f6f0f447d0fcd9c64743]
sensor_msgs/Imu [6a62c6daae103f4ff57a132d6f95cec2]
topics: /cam0/image_raw 3682 msgs : sensor_msgs/Image
/cam1/image_raw 3682 msgs : sensor_msgs/Image
/imu0 36820 msgs : sensor_msgs/Imu
/leica/position 3099 msgs : geometry_msgs/PointStamped
显然,图像没有压缩,来自/cam0/image_raw话题首先编写一个订阅节点listener.cpp
#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
long temptime=0;
char base_name[256];
string str;
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
cout<<"callback OK"<<endl;
cv::imshow("view", cv_bridge::toCvShare(msg,"mono8")->image);
cv::waitKey(1);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "image_listener");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("/cam0/image_raw", 1, imageCallback);
ros::spin();
cv::destroyWindow("view");
}
注意,图像是灰度突,所以解码方式为"mono8",订阅的是"cam0/image_raw"话题,修改CMakeLists文件,catkin_make编译后运行程序,
rosrun beginner_tutorials listener
最后,回放bag数据,就可以显示图像。
rosbag play /home/amor/Desktop/XL/dataset/EuRoC_MAV/MH_01_easy.bag
其中/home/amor/Desktop/XL/dataset/改成你自己的路径。
结果如下图