在ROS中使用USB网络摄像头传输图像

转自:http://blog.csdn.net/yake827/article/details/44983093

在上节已经实现了单张图片的ROS实现,而在现实中,我们一般是使用摄像头来获取图像,这次要实现在ROS中使用摄像头传输图像,我使用的是罗技的usb网络摄像头,首先我们需要获取摄像头的型号,如下所示:

[plain]  view plain  copy
  1. yake@yake-K42JE:~$ lsusb  
  2. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  
  3. Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  
  4. Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub  
  5. Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub  
  6. Bus 001 Device 003: ID 04f2:b1e5 Chicony Electronics Co., Ltd   
  7. Bus 002 Device 003: ID 046d:c058 Logitech, Inc. M115 Mouse  
  8. Bus 002 Device 008: ID 046d:0825 Logitech, Inc. Webcam C270  

我所使用的是罗技的C270网络摄像头.接下来我们要为摄像头安装驱动,我使用的是cheese点击打开链接,这个驱动的好处是在ubuntu环境下直接apt-get获得

[plain]  view plain  copy
  1. yake@yake-K42JE:~$ sudo apt-get install cheese  

安装完成后,插上摄像头可以发现在dev/目录下多了一个viedo0的设备,这个说明摄像头驱动已经安装完成.接下来开始在ROS中使用它.使用的方式是通过opencv函数来实现.

首先还是要创建一个包,写一个驱动摄像头的文件,命名为my_publisher.cpp,作用是获取图像并打包成ros格式发送出去,创建包的方法与单张图片一样,my_publisher.cpp内容如下:

[plain]  view plain  copy
  1. #include <ros/ros.h>  
  2. #include <image_transport/image_transport.h>  
  3. #include <opencv2/highgui/highgui.hpp>  
  4. #include <cv_bridge/cv_bridge.h>  
  5. #include <sstream> // for converting the command line parameter to integer  
  6.   
  7. int main(int argc, char** argv)  
  8. {  
  9.   // Check if video source has been passed as a parameter  
  10.   if(argv[1] == NULL)   
  11.     {  
  12.             ROS_INFO("argv[1]=NULL\n");  
  13.         return 1;  
  14.     }  
  15.   
  16.   ros::init(argc, argv, "image_publisher");  
  17.   ros::NodeHandle nh;  
  18.   image_transport::ImageTransport it(nh);  
  19.   image_transport::Publisher pub = it.advertise("camera/image", 1);  
  20.   
  21.   // Convert the passed as command line parameter index for the video device to an integer  
  22.   std::istringstream video_sourceCmd(argv[1]);  
  23.   int video_source;  
  24.   // Check if it is indeed a number  
  25.   if(!(video_sourceCmd >> video_source))   
  26.   {  
  27.       ROS_INFO("video_sourceCmd is %d\n",video_source);  
  28.       return 1;  
  29.   }  
  30.   
  31.   cv::VideoCapture cap(video_source);  
  32.   // Check if video device can be opened with the given index  
  33.   if(!cap.isOpened())   
  34.   {  
  35.       ROS_INFO("can not opencv video device\n");  
  36.       return 1;  
  37.   }  
  38.   cv::Mat frame;  
  39.   sensor_msgs::ImagePtr msg;  
  40.   
  41.   ros::Rate loop_rate(5);  
  42.   while (nh.ok()) {  
  43.     cap >> frame;  
  44.     // Check if grabbed frame is actually full with some content  
  45.     if(!frame.empty()) {  
  46.       msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();  
  47.       pub.publish(msg);  
  48.       //cv::Wait(1);  
  49.     }  
  50.   
  51.     ros::spinOnce();  
  52.     loop_rate.sleep();  
  53.   }  
  54. }  

再写一个my_subscriber.cpp,作用是获取ROS图像并显示,内容如下:

[plain]  view plain  copy
  1. #include <ros/ros.h>  
  2. #include <image_transport/image_transport.h>  
  3. #include <opencv2/highgui/highgui.hpp>  
  4. #include <cv_bridge/cv_bridge.h>  
  5.   
  6. void imageCallback(const sensor_msgs::ImageConstPtr& msg)  
  7. {  
  8.   try  
  9.   {  
  10.     cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);  
  11.    // cv::WaitKey(30);  
  12.   }  
  13.   catch (cv_bridge::Exception& e)  
  14.   {  
  15.     ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());  
  16.   }  
  17. }  
  18.   
  19. int main(int argc, char **argv)  
  20. {  
  21.   ros::init(argc, argv, "image_listener");  
  22.   ros::NodeHandle nh;  
  23.   cv::namedWindow("view");  
  24.   cv::startWindowThread();  
  25.   image_transport::ImageTransport it(nh);  
  26.   image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);  
  27.   ros::spin();  
  28.   cv::destroyWindow("view");  
  29. }  

接下来要把设计到的各种包和opencv在CmakeList中声明一下,添加以下语句

[plain]  view plain  copy
  1. find_package(OpenCV REQUIRED)  
  2. # add the publisher example  
  3. add_executable(my_publisher src/my_publisher.cpp)  
  4.   
  5. target_link_libraries(my_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})  
  6.   
  7. # add the subscriber example  
  8. add_executable(my_subscriber src/my_subscriber.cpp)  
  9. target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})  

将这个包进行编译

[plain]  view plain  copy
  1. yake@yake-K42JE:~/ros_ws$ catkin_make  

编译过程可能会出现错误,其中一个就是cv::WaitKey不能识别,这个问题到最后依然没有解决,我是直接把它注释掉,这样也没什么影响.接下来开始运行程序,首先启动ROS.

[plain]  view plain  copy
  1. yake@yake-K42JE:~$ roscore  

运行my_publisher节点.(如果运行不起来,需要先source devel/setup.bash)

[plain]  view plain  copy
  1. yake@yake-K42JE:~/video_ros$ rosrun learning_image_transport my_publisher 0  
这时候会看到我们的摄像头灯已经亮起来了,0代表默认摄像头,如果有多个摄像头,则第二个是1,依次类推.

接下来运行my_subscriber节点来接收图像

[plain]  view plain  copy
  1. yake@yake-K42JE:~/video_ros$ rosrun learning_image_transport my_subscriber  

这时候如果没有错误的话就会弹出图像窗口


可以看到我们摄像头传输出来的图像,到此,整个程序结束!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在ROS打开USB摄像头并将消息以规定的消息发送,需要进行以下步骤: 1. 安装ROS包:要使用USB摄像头,需要安装ROS的`usb_cam`包。可以使用以下命令进行安装: ``` sudo apt-get install ros-<distro>-usb-cam ``` 其,`<distro>`指代你使用ROS版本,比如`melodic`。 2. 连接摄像头:将USB摄像头连接到计算机,并确保摄像头被正确识别。 3. 启动节点:在终端输入以下命令,启动`usb_cam`节点: ``` roscore rosrun usb_cam usb_cam_node ``` 4. 发布消息:`usb_cam`节点会将摄像头图像发布到ROS的`/usb_cam/image_raw`话题。可以使用以下命令查看消息: ``` rostopic echo /usb_cam/image_raw ``` 如果想将消息以规定的消息类型发送,可以使用ROS的`image_transport`包。例如,将消息换为JPEG格式并发送到`/image_jpeg/compressed`话题: ``` rosrun image_transport republish raw in:=/usb_cam/image_raw out:=/image_jpeg/compressed jpeg ``` 这样,就可以在其他节点订阅`/image_jpeg/compressed`话题,接收JPEG格式的图像消息了。 ### 回答2: ROS(机器人操作系统)是一个开源的软件平台,用于构建机器人应用程序。它提供了许多功能库和工具,可以帮助开发者快速构建和管理机器人系统。 要打开USB摄像头并将消息以规定的message发送,我们可以使用ROS提供的功能库和工具。 首先,我们需要使用ROS图像工具包(image\_transport)来打开USB摄像头。该工具包提供了用于传输和处理图像数据的功能。 我们可以通过运行以下命令来启动USB摄像头节点: ``` $ rosrun usb_cam usb_cam_node ``` 此命令将启动一个节点,它将创建一个图像话题(image topic)来发布摄像头图像数据。 接下来,我们需要使用ROS的发布者(Publisher)来发送消息。我们可以创建一个新的ROS节点,并在其创建一个发布者来发送消息。 创建一个新的ROS节点的命令如下: ``` $ roscpp_create_pkg camera_publisher ``` 这将创建一个名为camera\_publisher的ROS包。 我们可以在新创建的节点文件添加发布者的逻辑。在节点的代码文件,我们首先需要包含ROS的头文件,以便使用ROS的功能。 然后,我们可以创建一个发布者实例,指定要发布的消息类型。 例如,我们可以创建一个名为image\_publisher的发布者对象,并指定要发布的消息类型为sensor\_msgs/Image。然后,我们可以调用发布者对象的publish()函数来发布摄像头图像数据。 最后,我们需要使用catkin构建系统,编译并运行我们的节点: ``` $ cd camera_publisher $ catkin_make $ source devel/setup.bash $ rosrun camera_publisher camera_publisher_node ``` 这将编译并运行camera\_publisher节点,并开始发送摄像头图像数据的消息。 以上就是使用ROS打开USB摄像头并将消息以规定的message发送的过程。通过使用ROS的功能库和工具,我们可以方便地实现这个功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值