ROS中usb摄像头的使用_(usb_cam)

http://xiaoyatec.com/2015/10/10/ros%E4%B8%ADusb%E6%91%84%E5%83%8F%E5%A4%B4%E7%9A%84%E4%BD%BF%E7%94%A8_usb_cam/

环境:

Ubuntu12.04

ROS Hydro version

特别标注:

这篇文章首发于“北京小芽科技有限公司”的技术博客(xiaoyatec.com)上,所有版权归属于北京小芽科技有限公司。更多相关信息请关注北京小芽科技、小芽机器人。

正文:

ROS的学习中,在使用USB摄像头的时候,安装和使用的过程中,遇到了一些问题,现在对学习的过程这问题做一个整理。

首先,根据《ros_by_example_hydro___volume_1》(在写这篇文档时20141215,此书还不免费公开,需要付费购买,尊重版权,这里就不做分享了,望谅解,可以参考groovy版本,网上有免费下载)教程,下载安装uvc_cam功能包安装


但是期间在编译的时候遇到各种问题,搞得焦头烂额。

继续网上找资料和解决方式,发现另外一种驱动方式:usb_cam

这个驱动方式是在网上的一篇文章里看到的Testing: ROS USB Camera drivers

链接地址为:

http://www.iheartrobotics.com/2010/05/testing-ros-usb-camera-drivers.html 

里面给出了几种usb摄像头驱动的方式,根据给出的分析和建议,我最终选择了usb_cam驱动方式。下面就来说说usb_cam使用的流程。

这是说的是外置USB摄像头的驱动和使用方式,其实内置和外置的使用方式都是一样的原理,稍作设备信息的修改即可通用了。

对于USB摄像头的图像获取, 要比Kinect或Xtion的复杂, 原因是在图像Topic的发布阶段需要我们自己做操作,而Kinect或者Xtion在ROS里边就已经有成型的Topic发布机制。但在图像接收并显示的阶段就非常相似了。 

这里只说摄像头的驱动和使用方式,涉及到ROS原理性的东西这里只做简单但不详细的介绍。

先来简单说一下整个流程的工作原理吧。

ROS是一个分布式系统,节点是它运行的基本单元,节点说得通俗一点就是一个可运行的功能程序,也可以叫做一个进程,节点与节点之间的通信通过主题来体现。拿这个驱动usb摄像头并显示图像这个工程来说,大体上这里边就涉及到两个节点:摄像头驱动节点,以及获取图像并显示节点;同时涉及到一个主题,这两个节点通过这个主题来进行交互:

现在以节点的方式进行描述:

1、 usb_cam设备驱动程序节点:

首先,创建一个usb_cam的工作空间

 

进入到src源码文件夹里边:

然后从git中下载usb_cam包(记得安装git工具,方法在文章的开头处)

下载成功之后显示如下信息:

包含的内容如下:

现在插上USB摄像头,看看在设备文件夹里边显示的是什么名称,我的显示名称为“video0”,打开源码包里的nodes文件夹,用编辑工具打开usb_cam_node.cpp源文件,找到下面这句:

然后根据自己的设备名称修改相应的信息,我的名称和这里默认的“/dev/video0”刚好一样,所以不用做修改。

这里还得注意一个小问题,就是在usb_cam_node.cpp源文件里边,对于主题的发布:

得在主题名称“image_raw”前面加上一个反斜杠“/”,如下所示:

这样编译之后才能成功发布图形。

下来还得注意另外一个问题,就是关于图形格式的问题,在usb_cam_node.cpp源文件里边

这一行是对摄像头的格式进行设置的,具体的格式得根据你的摄像头来去定,我的摄像头能够输出的格式是yuyv格式。(如果不清楚自己使用的是什么格式,上面提示里边给出的5种格式建议都试验一遍)

好,至此,usb_cam设备驱动程序节点就构造成功了,现在回到工作空间的根目录,对工程进行catkin_make编译,编译成功之后显示如下:

对应的生产的可运行的节点文件位于:~/catkin_ws_usbcam/devel/lib/usb_cam文件夹里边:

2、 图像接收与显示节点的构建

这里边涉及到ROS图像和Opencv图像的转换,可参阅以下的文献

Converting between ROS images and OpenCV images

首先,创建节点工作空间,然后进入到源文件夹里边,创建cvbridge包,以及其依赖项:

运行成功后,将生成如下文件:

现在进入到cvbridge文件夹的src文件夹里边,编写image_converter.cpp节点源文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

#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 = "Image window";

 

class ImageConverter

{

    ros::NodeHandle nh_;

    image_transport::ImageTransport it_;

    image_transport::Subscriber image_sub_;

    image_transport::Publisher image_pub_;

 

public:

    ImageConverter()

    : it_(nh_)

    {

        // Subscrive to input video feed and publish output video feed

        image_sub_ = it_.subscribe("/image_raw", 1,//注意此处主题名称的写法

        &ImageConverter::imageCb, this);

        image_pub_ = it_.advertise("/image_converter/output_video", 1);

 

        cv::namedWindow(OPENCV_WINDOW);

    }

 

    ~ImageConverter()

    {

        cv::destroyWindow(OPENCV_WINDOW);

    }

 

    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, cv_ptr->image);

        cv::waitKey(3);

        

        // Output modified video stream

        image_pub_.publish(cv_ptr->toImageMsg());

    }

};

 

int main(int argc, char** argv)

{

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

    ImageConverter ic;

    ros::spin();

    return 0;

}

 

下来,修改cvbridge文件夹里的CMakeList.txt文件,在其后面添加如下信息:

回到工作空间的根目录,进行catkin_make编译

编译成功之后,可执行文件节点生成于 “~/catkin_ws_cvbridge/devel/lib/cvbridge”文件夹中

至此,图像接收和显示节点已经构建完成。

3、 现在来运行节点:

分别打开三个终端:

第一个终端先运行以下两条命令:

第二个终端运行以下两个命令:(usb摄像头驱动程序节点)

第三个终端运行以下两个命令:(图像接收和显示检点)

成功运行之后摄像头图像非常流畅。

参考文献:

1、Testing: ROS USB Camera drivers

链接地址为:

http://www.iheartrobotics.com/2010/05/testing-ros-usb-camera-drivers.html 

2、Converting between ROS images and OpenCV images

链接地址为:

http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages

3、《机器人操作系统ROS_典型功能实现方法详解》

链接地址为:

http://wenku.baidu.com/link?url=IQSHfjUomZ8jtnXLyz7dSVb5AebOcBt4b8C5PRxVSeQPxSaXaYSiiSy60NulCYIFlQcc-BTAF5x6YfNnx9f2KUIBRT0eheQsmDEk0ReWZ8q

 

猜你喜欢

转载自blog.csdn.net/chengde6896383/article/details/82429862