参考的博客
ROS学习笔记47(ROS图像和OpenCV图像之间的转换(C ++))
如何使用ROS的service读取Kinect图像
使用kinect2进行目标跟踪-ROS平台
深度图从ros数据类型转换成了opencv数据类型
概念
ROS以自己的sensor_msgs / Image消息格式传递图像,但许多用户希望将图像与OpenCV结合使用。
CvBridge是一个ROS库,提供ROS和OpenCV之间的接口。
CvBridge可以在cv_bridge包在vision_opencv stack找到。
使用CvBridge将ROS图像转换为OpenCV cv :: Mat格式的节点。
将OpenCV图像转换为ROS格式,并以通过ROS发布。
将ROS图像消息转换为OpenCV图像
CvBridge定义了一个包含OpenCV图像的CvImage类型,its encoding and a ROS header。CvImage也包含sensor_msgs / Image的信息,因此我们可以将一个转换为另一个。
namespace cv_bridge {
class CvImage
{
public:
std_msgs::Header header;
std::string encoding;
cv::Mat image;
};
typedef boost::shared_ptr<CvImage> CvImagePtr;
typedef boost::shared_ptr<CvImage const> CvImageConstPtr;
}
将ROS sensor_msgs / Image消息转换为CvImage时,CvBridge会识别两个不同的用例:
- 我们想要就地修改数据。我们必须复制ROS消息数据。
- 我们不会修改数据。我们可以安全地共享ROS消息所拥有的数据,而不是复制。
CvBridge提供以下用于转换为CvImage的函数
// Case 1: Always copy, returning a mutable CvImage
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr& source,
const std::string& encoding = std::string());
CvImagePtr toCvCopy(const sensor_msgs::Image& source,
const std::string& encoding = std::string());
// Case 2: Share if possible, returning a const CvImage
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr& source,
const std::string& encoding = std::string());
CvImageConstPtr toCvShare(const sensor_msgs::Image& source,
const boost::shared_ptr<void const>& tracked_object,
const std::string& encoding = std::string());
输入是图像消息指针,以及可选的编码参数。编码 refers to目标CvImage。
即使源和目标编码匹配,toCvCopy也会从ROS消息创建图像数据的副本。不过,您可以自由修改返回的CvImage。
如果源和目标编码匹配,toCvShare将在ROS消息数据上指向返回的CV::Mat,避免复制。只要您还拥有返回的CvImage的副本,就不会释放ROS消息数据。
如果编码不匹配,它将分配一个新缓冲区并执行转换。您不能修改返回的CvImage,因为它可能与ROS图像消息共享数据,而ROS图像消息又可能与其他回调共享。
注意:如果您指向包含要转换的sensor_msgs / Image的其他消息类型(例如stereo_msgs / DisparityImage),则toCvShare的第二个重载函数会更方便。
如果没有给出编码(或者更确切地说是空字符串),则目标图像编码将与图像消息编码相同。在这种情况下,toCvShare保证不复制图像数据。图像编码可以是以下OpenCV图像编码中的任何一种:
- 8UC[1-4]
- 8SC[1-4]
- 16UC[1-4]
- 16SC[1-4]
- 32SC[1-4]
- 32FC[1-4]
- 64FC[1-4]
对于流行的图像编码,CvBridge可根据需要选择进行颜色或像素深度转换。要使用此功能,请将编码指定为以下字符串之一:
mono8:CV_8UC1,灰度图像
mono16:CV_16UC1,16位灰度图像
bgr8:CV_8UC3,彩色图像,蓝绿红色顺序
rgb8:CV_8UC3,带有红绿蓝颜色顺序的彩色图像
bgra8:CV_8UC4,带有alpha通道的BGR彩色图像
rgba8:CV_8UC4,带有alpha通道的RGB彩色图像
请注意,mono8和bgr8是大多数OpenCV函数所期望的两种图像编码。
最后,CvBridge会将Bayer pattern encodings识别为具有OpenCV类型8UC1(8位无符号,一个通道)。它不会与Bayer pattern进行转换; 在典型的ROS系统中,这是由image_proc完成的。CvBridge认可以下Bayer pattern:
bayer_rggb8
bayer_bggr8
bayer_gbrg8
bayer_grbg8
示例
这是一个侦听ROS图像消息主题的节点,将图像转换为cv :: Mat。然后通过ROS重新发布图像。
在package.xml和CMakeLists.xml中(或使用catkin_create_pkg时),添加以下依赖项:
sensor_msgs
cv_bridge
roscpp
std_msgs
image_transport
cv上障碍物的颜色特别白,分不清前后
TYPE_32FC1 这个编码格式 只有这个能正确显示
TYPE_8UC1 就全黑了
TYPE_16UC1 就全黑了
经过验证,ros的编码方式就是32FC1
再把cv的图像转换回去 还是 可以区分前后的
目前还没有确定 深度图像返回的是不是距离 应该是 ,但是数据是真对不上
depth_msg->encoding.c_str() 来确定数据类型
printf("%s",str) 打印字符串
depth_pic = depth_ptr->image;
// output some info about the depth image in cv format
cout<<"output some info about the depth image in cv format"<<endl;
cout<<"rows of the depth image = "<<depth_pic.rows<<endl;
cout<<"cols of the depth image = "<<depth_pic.cols<<endl;
cout<<"type of depth_pic's element = "<<depth_pic.type()<<endl; 5代表CV_32FC1
结果
计算距离
深度图的像素值代表距离吗? 可以计算距离,但像素并不是距离
从这篇博客看不是的