使用opencv结合ros来显示摄像图中的彩色图和深度图

Ros中的图像信息是sensor_msgs/Image的格式,而OpenCV 中图像是cv:Mat格式。所以从Ros中获取的图像不能直接用OpenCV进行处理,需要进行格式转化。还好,Ros中提供了进行ROS和OpenCV之间图像信息格式转化的接口CvBridge

代码如下:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
 
static const std::string OPENCV_WINDOW_COLOR = "Image color window";
static const std::string OPENCV_WINDOW_DEPTH = "Image depth window";
 
class ImageConverter
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Subscriber image_sub_color;
  image_transport::Subscriber image_sub_depth;
  image_transport::Publisher image_pub_color;
  image_transport::Publisher image_pub_depth;
 
public:
  ImageConverter()
    : it_(nh_)
  {
    // Subscrive to input video feed and publish output video feed
    image_sub_color = it_.subscribe("/camera/rgb/image_raw", 1, &ImageConverter::imageCb, this);
    image_sub_depth = it_.subscribe("/camera/depth/image_raw",1,&ImageConverter::depthCb, this);
    image_pub_color = it_.advertise("/image_converter/output_video/color", 1);
    image_pub_depth = it_.advertise("/image_converter/output_video/depth", 1);

 
    cv::namedWindow(OPENCV_WINDOW_COLOR);
    cv::namedWindow(OPENCV_WINDOW_DEPTH);
  }
 
  ~ImageConverter()
  {
    cv::destroyWindow(OPENCV_WINDOW_COLOR);
    cv::destroyWindow(OPENCV_WINDOW_DEPTH);
  }
 
  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }
 
    // Draw an example circle on the video stream
    if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));
 
    // Update GUI Window
    cv::imshow(OPENCV_WINDOW_COLOR, cv_ptr->image);
    cv::waitKey(3);
 
    // Output modified video stream
    image_pub_color.publish(cv_ptr->toImageMsg());
  }

  void depthCb(const sensor_msgs::ImageConstPtr &msg)
  {
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_32FC1);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

     // Draw an example circle on the video stream
    if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

    // Update GUI Window
    cv::imshow(OPENCV_WINDOW_DEPTH, cv_ptr->image);
    cv::waitKey(3);
 
    // Output modified video stream
    image_pub_depth.publish(cv_ptr->toImageMsg());

  }
};
 
int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_converter");
  ImageConverter ic;
  ros::spin();
  return 0;
}

编译后可能会出现很多未定义的引用

image_rec_handle.cpp:(.text._ZN14ImageConverterD2Ev[_ZN14ImageConverterD5Ev]+0x35):对‘cv::destroyWindow(cv::String const&)’未定义的
CMakeFiles/image_rec_handle.dir/src/image_rec_handle.cpp.o:在函数‘ImageConverter::imageCb(boost::shared_ptr<sensor_msgs::Image_<st
image_rec_handle.cpp:(.text._ZN14ImageConverter7imageCbERKN5boost10shared_ptrIKN11sensor_msgs6Image_ISaIvEEEEE[_ZN14ImageConverter7
_msgs6Image_ISaIvEEEEE]+0x1bd):对‘cv::imshow(cv::String const&, cv::_InputArray const&)’未定义的引用
image_rec_handle.cpp:(.text._ZN14ImageConverter7imageCbERKN5boost10shared_ptrIKN11sensor_msgs6Image_ISaIvEEEEE[_ZN14ImageConverter7
_msgs6Image_ISaIvEEEEE]+0x1e2):对‘cv::waitKey(int)’未定义的引用
collect2: error: ld returned 1 exit status

这是因为 package.xml 和cmakelist.txt中少了关于opencv的信息。添加后即可编译成功。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
另外,深度图有好几种不同的编码方式,我这里摄像头的编码方式是32FC1

在上述代码中, sensor_msgs::image_encodings::TYPE_16UC1表示将ros数据类型转换cv数据类型的编码方式。一般而言,深度图的编码方式都有8UC, 16UC1, 32FC1等三种。

参考文献:
https://blog.csdn.net/Jaryblueky/article/details/70895270
https://blog.csdn.net/jchsns007/article/details/78908164
https://www.cnblogs.com/gdut-gordon/p/9151740.html

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值