ROS USB_cam功能包

2023-12-19 22:54:23

ROS中的USB_cam功能包是一个用于与USB摄像头交互的软件包。这个软件包可以订阅摄像头的图像话题,并将其发布到ROS中,从而允许用户在ROS系统中使用USB摄像头。 ???

功能:

?????USB_cam功能包主要用于获取USB摄像头的图像数据

?????它通过调用V4L2(Video for Linux 2)接口来与摄像头硬件通信。

?????USB_cam发布图像数据为ROS的标准消息类型sensor_msgs/Image,这使得图像数据可以被其他ROS节点方便地订阅和处理。

用法:

????启动USB_cam节点:在终端中,进入USB_cam的launch文件目录,然后运行以下命令:

roslaunch usb_cam usb_cam-test.launch

这将会启动USB_cam节点,并开始从默认的USB摄像头获取图像。

参数配置:

USB_cam提供了一些参数供用户自定义,包括设备名称、图像大小、帧率、颜色模式等。这些参数可以在launch文件中进行修改,或者通过rosparam命令在运行时设置。

以下是一些常见的参数:

????video_device:?指定USB摄像头的设备路径,如 /dev/video0。

????image_width?和 image_height:?设置图像的分辨率。

????frame_rate: 设置帧率。

????pixel_format:?设置像素格式,如 yuyv 或 mjpeg。

订阅图像话题:

USB_cam发布的图像话题通常命名为/<camera_name>/image_raw,其中<camera_name>是你在启动节点时指定的名称,或者默认为usb_cam。

一般来说,需要配合image_transportcv_bridge这两个功能包一起使用。image_transport用于处理图像传输,而cv_bridge则用于将OpenCV图像转换为ROS图像消息。

#include <ros/ros.h>

#include <image_transport/image_transport.h>

#include <cv_bridge/cv_bridge.h>

#include <sensor_msgs/Image.h>

int main(int argc, char** argv)

{

????ros::init(argc, argv, "usb_cam_example");

????ros::NodeHandle nh;

????image_transport::ImageTransport it(nh);

????image_transport::Publisher pub = it.advertise("camera/image_raw", 1);

????cv_bridge::CvImage cv_image;

????cv::Mat image;

????while (ros::ok())

????{

????????// 从USB摄像头获取图像

????????// ...

????????// 将OpenCV图像转换为ROS图像消息

????????cv_image = cv_bridge::CvImage(cv_image.encoding, cv_image.image.size(), image);

????????sensor_msgs::Image msg = cv_image.toImageMsg();

????????// 发布图像消息

????????pub.publish(msg);

? ? ? ? ros::spinOnce();

????}

? ?return 0;

}

在这个示例中,首先初始化了一个ROS节点,并创建了一个image_transport::ImageTransport对象和一个image_transport::Publisher对象。然后,在一个循环中不断地从USB摄像头获取图像,将其转换为ROS图像消息,并发布到"camera/image_raw"话题上。

image_transport是一个中间件,它为ROS中的图像消息传输提供了抽象层。它允许开发者选择不同的传输方式(插件)来优化图像数据的传输,如压缩、多分辨率传输等。

image_transport支持多种传输方式,如compressed, theora, jpeg, png, 和未压缩的raw格式。这些插件可以在运行时动态加载,提供了很大的灵活性。

双向通信:image_transport不仅支持发布图像,也支持订阅图像。

支持传输参数:可以通过ROS参数服务器配置传输参数,如压缩级别、帧率等。

1、发布图像

首先,需要包含相应的头文件并创建一个image_transport的Publisher:

#include <ros/ros.h>

#include <sensor_msgs/Image.h>

#include <image_transport/image_transport.h>

ros::NodeHandle nh;

image_transport::ImageTransport it(nh);

image_transport::Publisher pub = it.advertise("camera/image", 1);

然后,当有新图像数据可用时,可以使用pub.publish()方法发布图像:

sensor_msgs::ImagePtr image_msg(new sensor_msgs::Image());

// ...填充image_msg的数据...

pub.publish(image_msg);

2、订阅图像

创建一个image_transport的Subscriber来接收图像:

#include <ros/ros.h>

#include <sensor_msgs/Image.h>

#include <image_transport/image_transport.h>

#include <cv_bridge/cv_bridge.h>

#include <opencv2/highgui/highgui.hpp>

ros::NodeHandle nh;

image_transport::ImageTransport it(nh);

image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);

void imageCallback(const sensor_msgs::ImageConstPtr& msg)

{

????cv_bridge::CvImagePtr cv_image = cv_bridge::toCvCopy(msg, "bgr8");

????cv::imshow("Image Window", cv_image->image);

????cv::waitKey(30);

}

在回调函数中,可以使用cv_bridge将接收到的ROS Image消息转换为OpenCV格式进行处理和显示。

其他功能:

Republish: 可以使用republish工具将一种传输方式的消息转换为另一种传输方式,

例如将未压缩的图像转换为压缩图像。

Display: display工具可以用于可视化接收到的图像。

cv_bridge它主要用于在ROS的图像消息格式和OpenCV的图像数据格式之间进行转换。

目的是解决ROS和OpenCV之间的图像数据格式差异。ROS使用自己的图像消息类型(sensor_msgs/Image),而OpenCV则使用其内部的数据结构(cv::Mat)

1、从ROS消息转换到OpenCV图像:

#include <ros/ros.h>

#include <image_transport/image_transport.h>

#include <cv_bridge/cv_bridge.h>

#include <sensor_msgs/image_encodings.h>

#include <opencv2/highgui/highgui.hpp>

void imageCallback(const sensor_msgs::ImageConstPtr& msg)

{

??try

??{

????//将ROS图像消息转换为OpenCV格式

????cv::Mat frame = cv_bridge::toCvCopy(msg, "bgr8")->image;

????//可以将'frame'当作普通的OpenCV图像来使用

????cv::imshow("Image Window", frame);

????cv::waitKey(3);

??}

??catch (cv_bridge::Exception& e)

??{

????ROS_ERROR("Could not convert from ROS message to OpenCV image: %s", e.what());

??}

}

int main(int argc, char** argv)

{

??ros::init(argc, argv, "image_converter");

??ros::NodeHandle nh;

//创建一个ImageTransport对象,用于订阅和发布图像

??image_transport::ImageTransport it(nh);

//订阅输入图像主题

??image_transport::Subscriber sub = it.subscribe("/camera/image_raw", 1, imageCallback);

??ros::spin();

??return 0;

}

在这个例子中,首先创建了一个cv_bridge::CvImagePtr对象,然后使用toCvCopy()函数将ROS的图像消息转换为OpenCV的cv::Mat格式。

2、从OpenCV图像转换到ROS消息:

#include <ros/ros.h>

#include <image_transport/image_transport.h>

#include <cv_bridge/cv_bridge.h>

#include <sensor_msgs/image_encodings.h>

#include <opencv2/highgui/highgui.hpp>

void publishImage(const cv::Mat& frame)

{

//创建一个ROS图像消息

sensor_msgs::ImagePtrmsg=cv_bridge::CvImage(std_msgs::Header(),"bgr8",frame).toImageMsg();

?//发布图像消息

??image_pub.publish(msg);

}

int main(int argc, char** argv)

{

??ros::init(argc, argv, "opencv_to_ros_image");

??ros::NodeHandle nh;

//创建一个用于发布图像的ImageTransport对象

??image_transport::ImageTransport it(nh);

//创建一个用于输出图像主题的发布者(publisher)

??image_transport::Publisher image_pub = it.advertise("/output/image", 1);

??//加载一个OpenCV图像

??cv::Mat frame = cv::imread("input.jpg");

??// 将OpenCV图像转换并作为ROS消息发布出去

??publishImage(frame);

??ros::spin();

??return 0;

}

在这个例子中,首先创建了一个cv_bridge::CvImage对象,然后使用toImageMsg()函数将其转换为ROS的图像消息类型(sensor_msgs/Image)。最后,将这个消息发布到指定的图像主题。

文章来源:https://blog.csdn.net/2301_79503228/article/details/135095274
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。