ROS订阅Image话题,转换为OpenCV图像

需求:从realsense相机发布的话题中拿到rgb图像和depth图像,并进行后续处理。ROS中提供了cv_bridge类帮助我们在ROS和OpenCV图像格式间转换。

订阅方需要用image_transport定义一个对象it,然后定义两个Subscriber对象,分别用来回调rgb和depth话题。

	// 初始化ros节点
    ros::init(argc, argv, "RGBD");
    // 创建ros节点句柄
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    // 回调函数队列长度为x,因此spinOnce每次执行完队列函数,相当于每x帧取1帧
    image_transport::Subscriber rgb_sub = it.subscribe("rgb", 1, rgbCallback);
    image_transport::Subscriber depth_sub = it.subscribe("depth", 1, depthCallback);

当cv_bridge将ROS的图像消息转换为OpenCV图像格式时都是通过CvImage类实现的。一般来说,cv_bridge提供了两种方式转换为CvImage类,分别为复制(copy)和共享(share)。

  • toCvCopy函数会从ROS消息中拷贝一个图像数据,不管如何修改CvImage类的内容都不会影响源数据
  • toCvShare函数则是在源和编码都匹配的情况下将返回的OpenCV指针指向ROS的消息,即共享指针。它的特点是只要你还保持着返回的CvImage类的副本,那么ROS的消息类型就不会被释放。

CvBridge中常用的编码有以下几种:

  • mono8: CV_8UC1, grayscale image

  • mono16: CV_16UC1, 16-bit grayscale image

  • bgr8: CV_8UC3, color image with blue-green-red color order

  • rgb8: CV_8UC3, color image with red-green-blue color order

  • bgra8: CV_8UC4, BGR color image with an alpha channel

  • rgba8: CV_8UC4, RGB color image with an alpha channel

cv_bridge::toCvShare(msg, "bgr8")是将msg转换为 CV_8UC3 的图像,然后得到指向msg的共享指针,->image就是取得图像,格式为cv::Mat。可以理解为浅拷贝。

rgb = cv_bridge::toCvShare(msg, "bgr8")->image;

cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)也是将msg转换为 CV_8UC3 的图像,但是它只指向转换后的图像,格式为cv::Mat。可以理解为深拷贝。

cv::Mat rgb;
cv::Mat depth;

// rgb图像的回调函数,当有图像消息到达rgb时,就会被调用
void rgbCallback(const sensor_msgs::ImageConstPtr& msg) {
    try {           
        // ROS图像消息——>OpenCV图像
        rgb = cv_bridge::toCvShare(msg, "bgr8")->image;
        // cv::imshow("image", rgb);
        // cv::waitKey(50);
        // cout << "I have received rgb image!" << endl;
        // rgb = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)->image;
        
    } catch(cv_bridge::Exception& e) {
        ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }
}

// depth深度图像的回调函数
void depthCallback(const sensor_msgs::ImageConstPtr& msg) {
    try {           
        // ROS图像消息——>OpenCV图像
        depth = cv_bridge::toCvShare(msg, "mono16")->image;
        // cout << "I have received depth image!" << endl;
    } catch(cv_bridge::Exception& e) {
        ROS_ERROR("Could not convert from '%s' to 'mono16'.", msg->encoding.c_str());
    }
}

人言是牡丹,佛说是花箭。射人入骨髓,死而不知怨。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用ROS中的cv_bridge库来实现ROS图像消息与OpenCV图像之间的转换。 以下是将ROS图像消息转换OpenCV图像的示例代码: ```python import cv2 import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError bridge = CvBridge() def img_callback(msg): try: cv_image = bridge.imgmsg_to_cv2(msg, "bgr8") except CvBridgeError as e: rospy.logerr(e) # 在这里进行一些对OpenCV图像的更改 cv_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY) try: ros_image = bridge.cv2_to_imgmsg(cv_image, "mono8") except CvBridgeError as e: rospy.logerr(e) # 发布更改后的ROS图像消息 pub.publish(ros_image) rospy.init_node("image_converter") # 订阅原始ROS图像消息 sub = rospy.Subscriber("/camera/image_raw", Image, img_callback) # 发布更改后的ROS图像消息 pub = rospy.Publisher("/camera/image_processed", Image, queue_size=10) rospy.spin() ``` 在示例代码中,我们首先使用`imgmsg_to_cv2()`函数将ROS图像消息转换OpenCV图像。然后,我们在这里对OpenCV图像进行了一些更改,例如将彩色图像转换为灰度图像。然后,我们使用`cv2_to_imgmsg()`函数将更改后的OpenCV图像转换ROS图像消息,并将其发布到`/camera/image_processed`主题上。 请注意,我们在使用`imgmsg_to_cv2()`和`cv2_to_imgmsg()`函数时需要指定图像编码。在本例中,我们将原始ROS图像消息编码为`bgr8`,将更改后的OpenCV图像编码为`mono8`,这两种编码都适用于8位灰度或彩色图像。 最后,我们使用`rospy.spin()`来保持节点处于运行状态,以便继续接收和发布图像消息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

振华OPPO

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值