参考:https://blog.csdn.net/qq_34570910/article/details/88990373
比较完整的rosbag指令介绍:ROS-wiki
下面写一些我遇到的问题及解决方案:
问题1:
rosbag record -o /home/inin/data/ /occam/image_tiles0 /occam/stitched_image0
我在执行以上指令录包时会出现丢包的现象,结果如下:
[ INFO] [1554260232.649125239]: Subscribing to /occam/image_tiles0
[ INFO] [1554260232.651262266]: Subscribing to /occam/stitched_image0
[ INFO] [1554260232.653578956]: Recording to /home/inin/data/_2019-04-03-10-57-12.bag.
[ WARN] [1554260241.161152134]: rosbag record buffer exceeded. Dropping oldest queued message.
原因在于我记录的是原始图像,非常大(10s=5g),而rosbag的缓存空间与磁盘写入带宽有限,因此可以从两方面着手。
解决方案1:
法1. 提高rosbag的缓存空间:
rosbag record -o /home/inin/data/ -b 4096 /occam/stitched_image0 /occam/image_tiles0
指令如上所示,rosbag 中加入-b num
,即为将缓存空间设置成num大小,在ROS-wiki也有说明。
play之后可视化可用:
rosrun image_view image_view image:=/occam/image_tiles0
ros订阅:
class Images
{
public:
image_transport::Subscriber sub_image;these
Images()
{
ros::NodeHandle node;
image_transport::ImageTransport it(node);
sub_image = it.subscribe("/usb_cam/image_raw", 1, &Images::imageCallback, this);
}
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
try
{
cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
cv::waitKey(30);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
}
}
};
int main(int argc, char **argv)
{
ros::init(argc, argv, "my_node");
ROS_INFO("my_node running...");
Images images;
ros::spin();
return 0;
}
法2. 压缩原始图像大小
rosbag record -o /home/inin/data/ /occam/stitched_image0/compressed /occam/image_tiles0/compressed
存储图像的压缩格式/compressed
,可有效减小数据写入大小(1min=1G),然而压缩后的图像是一种有损压缩对图像质量要求极高的情况慎用,当然一般做视觉计算是无所谓的,相当于把raw格式的图片转换为jpeg格式。
在可视化时指令也有所改变:
rosrun image_view image_view image:=/occam/image_tiles0 compressed
针对压缩图像的ros定义节点可以参考以下:
#include <ros/ros.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
void imageCallback(const sensor_msgs::CompressedImageConstPtr& msg)
{
try
{
cv::Mat image = cv::imdecode(cv::Mat(msg->data),1);//convert compressed image data to cv::Mat
cv::imshow("view", image);
cv::waitKey(10);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("Could not convert to image!");
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "image_listener");
ros::NodeHandle nh;
cv::namedWindow("view");
cv::startWindowThread();
ros::Subscriber sub = nh.subscribe("/usb_cam/image_raw/compressed", 1, imageCallback);
ros::spin();
cv::destroyWindow("view");
}
问题2:
从一个包含众多topic的rosbag中分离出我想要的topic:
rosbag filter 2000-01-07-01-07-03.bag split/only-tiles.bag "topic == '/occam/image_tiles0/compressed /InsInfo'"