ROS Kinetic + OpenCV 同一节点中订阅、发布图像

OpenCV基于ROS处理图像时经常需要在同一个节点中实现订阅和发布,像函数有输入输出一样,所以这样一个节点需要经历(1)订阅Topic、(2)ROS类型(sensor_msgs/Image)转换为Mat类型、(3)OpenCV处理图像、(4)Mat类型转换为ROS类型、(5)发布Topic这样五个步骤。下面的源码定义了一个可以实现这些功能的类,供大家作为模板编写自己需要的代码。

#include <iostream> 
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

using namespace std;
using namespace cv;

class SubscribeAndPublish
{
private:
	image_transport::Publisher  pub;
	image_transport::Subscriber sub;

public:
	SubscribeAndPublish(ros::NodeHandle &nh, image_transport::ImageTransport &it)
	{
		pub = it.advertise("/the/topic/to/be/published",1);
		sub = it.subscribe("/the/topic/to/be/subscribed", 1, &SubscribeAndPublish::callback, this);
	}

	void thresholdImage(const sensor_msgs::ImageConstPtr& msg, sensor_msgs::ImageConstPtr& out)
	{
		//Receive the input and convert it from ros type to cv type 
		Mat image = cv_bridge::toCvShare(msg, "bgr8")->image;
                Mat image_optput;
		//Do something using OpenCV with the input and generate the output...
	        /*...your code...*/
		//Convert the output from cv type to ros type and publish it
		out = cv_bridge::CvImage(std_msgs::Header(), "bgr8",image_optput).toImageMsg();
	}

	void callback(const sensor_msgs::ImageConstPtr& msg)
	{
		sensor_msgs::ImageConstPtr output;
		thresholdImage(msg,output);
		pub.publish(output);
	}
};//End of class SubscribeAndPublish
 
int main(int argc, char **argv)
{
	//Initiate ROS
	ros::init(argc, argv, "Node_Name");
	ros::NodeHandle nh;
	image_transport::ImageTransport it(nh);

	//cv::namedWindow("Image");
	//cv::startWindowThread();
	//Create an object of class SubscribeAndPublish that will take care of everything
	SubscribeAndPublish SAPObject(nh,it);

	ros::spin();
	//cv::destroyWindow("Image"); 
	return 0;
}

Tips:

    1. 根据输入输出图像格式改变关键字"bgr8",对应格式如下:

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

例如输出的image_output是灰度图,则改为“mono8”或“mono16”。

原文链接:Converting between ROS images and OpenCV images (C++) 

    2. 如果报错“error: invalid use of non-static member function”就在相应函数前加入关键字“static”。

    3. sub = it.subscribe("/the/topic/to/be/subscribed", 1, &SubscribeAndPublish::callback, this); //这一句在调用回调函数的时候名字要写全,不能只写callback,如果改了类的名称记得把这里也改掉;this不能省略。

    4. 非注释部分可以视为固定模板,只编辑/*...your code...*/部分即可。也就是说可以a.添加自定义成员数据和函数,b.编辑thresholdImage函数。其他部分不变。

    5. image_transport可能需要安装(Ubuntu 16.04下终端运行:sudo apt-get install ros-kinetic-image-transport-plugins)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,订阅ROS摄像头图像并处理可以分为以下几个步骤: 1. 安装ROS和相应摄像头驱动 在开始之前,需要确保ROS已经正确安装,同时需要安装相应的摄像头驱动。以ROS Kinetic和USB摄像头为例,可以使用以下命令安装: ``` sudo apt-get install ros-kinetic-usb-cam ``` 2. 创建ROS包和节点 使用ROS,我们需要创建ROS包和节点来管理我们的程序。可以使用以下命令创建一个名为“camera_processing”的ROS包: ``` catkin_create_pkg camera_processing rospy cv_bridge sensor_msgs ``` 然后可以使用以下命令创建一个名为“image_processor”的ROS节点: ``` rosrun camera_processing image_processor.py ``` 3. 编写代码 在创建了ROS包和节点之后,可以开始编写Python代码来订阅摄像头图像并进行处理。以下是一个基本的代码框架: ```python #!/usr/bin/env python import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2 def image_callback(msg): # 将ROS图像消息转换为OpenCV图像格式 bridge = CvBridge() cv_image = bridge.imgmsg_to_cv2(msg, "bgr8") # 进行图像处理 # ... # 显示图像 cv2.imshow("Image window", cv_image) cv2.waitKey(3) def main(): rospy.init_node('image_processor') rospy.Subscriber('/usb_cam/image_raw', Image, image_callback) rospy.spin() if __name__ == '__main__': main() ``` 在上面的代码,我们首先导入必要的ROSOpenCV库,然后定义了一个名为“image_callback”的回调函数,用于处理接收到的摄像头图像消息。在回调函数,我们首先将ROS图像消息转换为OpenCV图像格式,然后进行图像处理,最后显示图像。 在main函数,我们初始化了ROS节点,然后使用rospy.Subscriber函数订阅了名为“/usb_cam/image_raw”的摄像头图像话题,当有新的图像消息到达时,就会调用我们定义的回调函数进行处理。 4. 运行代码 最后,使用以下命令在终端运行ROS节点: ``` rosrun camera_processing image_processor.py ``` 如果一切正常,你应该能够看到摄像头的实时图像,并且你的代码可以对图像进行处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值