将ros的图像 转换成 opencv的图像并求距离

转载自:将ros的深度图像 转换成 opencv的图像 并求距离_月照银海似蛟龙的博客-CSDN博客

将ros的图像 转换成 opencv的图像并求距离

参考的博客

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;
 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

将ROS sensor_msgs / Image消息转换为CvImage时,CvBridge会识别两个不同的用例:

  1. 我们想要就地修改数据。我们必须复制ROS消息数据。
  2. 我们不会修改数据。我们可以安全地共享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());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输入是图像消息指针,以及可选的编码参数。编码 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
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述


 

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果

在这里插入图片描述

计算距离

深度图的像素值代表距离吗? 可以计算距离,但像素并不是距离
从这篇博客看不是的

在这里插入图片描述

版权声明:本文为qq_32761549原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:将ros的深度图像 转换成 opencv的图像 并求距离_月照银海似蛟龙的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值