1.使用usb_cam软件包调试usb摄像头
0x00 usb_cam软件包简介
为了丰富机器人与外界的交互方式,我们已经增加了与机器人的语音交互方式,不仅使机器人能够说话发声,还能听懂我们说的话,但是如果只有语音交互的话机器人就是一个盲人,无法看到这个色彩斑斓的大千世界,因此我们就需要为机器人增加视觉识别功能。现在市面上最常见的还是USB摄像头,物美价廉,要想使USB摄像头在ROS下正常工作,我们就需要一个软件包来支持,现在ROS下最常用的usb摄像头软件包就是usb_cam了,简单理解该软件包就是V4L(Video for Linux)USB摄像头驱动在ROS在的一个移植版本。截止到目前为止该软件包在indigo和jade版本上还处于维护状态,对于kinetic版本及其以上还未有维护,当然虽然没有维护但是在kinetic版本上也可以工作,但是考虑到稳定性方面,我们这里还是在indigo版本下做演示如何操作使用该软件包。
0x01 USB摄像头简介
我测试过很多款USB摄像头,最后还是具备自动对焦功能的摄像头对于移动型机器人更实用,因为机器人在移动过程中,需要不断的观察远距离和近距离的物体因此自动对焦是必须的,如果是用于工业上那种在固定距离上拍摄的话可以选择那种手动旋转镜头来对焦的摄像头,下面来分别介绍这两款摄像头,首先是具备自动对焦功能的摄像头,这款摄像头里面有个高速对焦马达会自动根据拍摄的视频清晰度来自动调整摄像头焦距:
接下来是需要手动旋转调整焦距的摄像头
以上两种摄像头是淘宝上比较常见的摄像头,当然大家也可以直接买那种台式机电脑上的摄像头,也是可以的价格也很便宜,如下图所示(图片中摄像头是淘宝随机搜到的,仅供参考):
0x02 通过apt来便捷安装usb_cam
在ROS WiKi上有usb_cam软件包的详细介绍,网址如下:
在indigo系统中安装usb_cam很方便,直接在终端中输入:
sudo apt-get install ros-indigo-usb-cam
在kinetic系统中安装命令如下:
sudo apt install ros-kinetic-usb-cam
当我们通过命令方便快捷的安装好usb_cam后,接下来简单查看下该软件包我们需要注意的部分:
一般情况下如果我们不需要对usb_cam进行深度修改定制的话,直接使用apt来安装就可以,我们只需要在自己创建的软件包中创建自己的launch文件,按照上图的usb_cam-test.launch文件内容格式复制一份差不多的,然后根据自己的需要修改下其中的param参数即可。
0x03 通过源码安装usb_cam软件包
当我们需要对usb_cam进行深度定制修改时就只能通过下载其源码,然后根据需要修改代码,最后编译启动运行就可以了,不过这个属于高级功能,一般情况下大家是不用下载源码来修改的,除非你非常熟悉usb_cam源码结构,自己需要的功能usb_cam无法满足时才需要下载源码修改。
下面我们在github上来下载该源码,github上的usb_cam源码网址如下:
https://github.com/ros-drivers/usb_cam
通过下图来查看整个下载操作流程:
下面来查看usb_cam源码介绍:
下载好源码后,接下来就可以根据需要修改和编译了,我这里只先演示如何编译,直接在catkin_ws目录下执行catkin_make即可:
corvin@workspace:~/catkin_ws$ catkin_make Base path: /home/corvin/catkin_ws Source space: /home/corvin/catkin_ws/src Build space: /home/corvin/catkin_ws/build Devel space: /home/corvin/catkin_ws/devel Install space: /home/corvin/catkin_ws/install #### #### Running command: "cmake /home/corvin/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/corvin/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/corvin/catkin_ws/install -G Unix Makefiles" in "/home/corvin/catkin_ws/build" #### -- Using CATKIN_DEVEL_PREFIX: /home/corvin/catkin_ws/devel -- Using CMAKE_PREFIX_PATH: /home/corvin/project/ros_voice_system/devel;/home/corvin/project/omniWheelCareRobot/rosCode/devel;/opt/ros/indigo -- This workspace overlays: /home/corvin/project/ros_voice_system/devel;/home/corvin/project/omniWheelCareRobot/rosCode/devel;/opt/ros/indigo -- Using PYTHON_EXECUTABLE: /usr/bin/python -- Using Debian Python package layout -- Using empy: /usr/bin/empy -- Using CATKIN_ENABLE_TESTING: ON -- Call enable_testing() -- Using CATKIN_TEST_RESULTS_DIR: /home/corvin/catkin_ws/build/test_results -- Found gtest sources under '/usr/src/gtest': gtests will be built -- Using Python nosetests: /usr/bin/nosetests-2.7 -- catkin 0.6.19 -- BUILD_SHARED_LIBS is on -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ~~ traversing 1 packages in topological order: -- ~~ - usb_cam -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- +++ processing catkin package: 'usb_cam' -- ==> add_subdirectory(usb_cam) -- Found PkgConfig: /usr/bin/pkg-config (found version "0.26") -- checking for module 'libavcodec' -- found libavcodec, version 54.35.1 -- checking for module 'libswscale' -- found libswscale, version 2.1.1 -- Configuring done -- Generating done -- Build files have been written to: /home/corvin/catkin_ws/build #### #### Running command: "make -j8 -l8" in "/home/corvin/catkin_ws/build" #### Scanning dependencies of target usb_cam [ 50%] Building CXX object usb_cam/CMakeFiles/usb_cam.dir/src/usb_cam.cpp.o Linking CXX shared library /home/corvin/catkin_ws/devel/lib/libusb_cam.so [ 50%] Built target usb_cam Scanning dependencies of target usb_cam_node [100%] Building CXX object usb_cam/CMakeFiles/usb_cam_node.dir/nodes/usb_cam_node.cpp.o Linking CXX executable /home/corvin/catkin_ws/devel/lib/usb_cam/usb_cam_node [100%] Built target usb_cam_node
0x04 启动launch打开摄像头
为了更为详细的介绍如何使用usb_cam来启动摄像头,我现在分如下几种操作方式,让大家可以对该软件包有更为全面的了解:
(1)直接使用apt安装的usb_cam来启动摄像头,直接在终端中运行命令,这样就不用自己来编写launch文件,但是只能打开一个摄像头,因为通过前面的usb_cam-test.launch得知默认启动的摄像头设备节点是usb_cam_node,如果接了两个摄像头的话再使用该命令就会导致节点相同,会导致将第一个同名节点杀掉:
如果现在接两个摄像头的话,如下操作可以打开第二个摄像头时会直接提示错误,由于usb_cam_node名字相同,该名字的修改只能通过修改launch才行,所以直接在命令后中使用默认的launch文件必然会导致启动的两个节点相同,这样就会第二个节点启动时,自动杀死第一个同名节点:
(2)在rviz中查看相机输出
0x05 校准摄像头
一般在我们使用usb_cam来启动相机时,如果没有校准过的话都会收到如下的警告,例如“[WARN] [1423194481.257752159]: Camera calibration file /home/xxx/.ros/camera_info/camera.yaml not found.”,对于"unknown control 'focus_auto'"的警告是由于启动的摄像头不具备自动对焦功能,如果启动的摄像头具备自动对焦功能的话,则没有这个警告提示。如下图所示:
一般情况如果只是拿摄像头作为视频监控功能的话就不用对相机做校准操作,只有在需要调用opencv功能对相机的视频流做图像处理,例如人脸识别,物体识别,使用立体相机或双目相机进行测距时才需要对相机进行校准。
为了从相机图像信息获得准确的距离信息,则需要多种附加信息,如每台相机各不相同的镜头特性、镜头与图像传感器之间的距离以及扭转角度等信息。这是因为相机是一个将我们生活的三维空间世界投影到二维空间的图像投影设备,所以在投影过程中,由于每台相机的固有特性,这些参数都会不同。
例如每台相机的镜头和图像传感器彼此不同,并且由于相机的硬件结构不同,镜头和图像传感器之间的距离也各不相同。并且在相机制作过程中,镜头和图像传感器必须水平组装,但由于细微的偏差,图像中心(image center)与主点(principal point)会有细微的偏离,且图像传感器的倾度也会略有差异。
校准这些部件的过程称为相机校准(Calibration),目的是查找相机的固有参数。摄像机的校准是非常重要的,ROS提供的是利用OpenCV相机校准的校准功能包,接下来我们按照如下步骤操作即可:
(1)安装相机校准软件包
在indigo中安装校准软件包命令如下:
sudo apt-get install ros-indigo-camera-calibration
在kinetic中安装校准软件包命令如下:
sudo apt install ros-kinetic-camera-calibration
但是在使用该校准软件包时需要启动uvc_camera软件包,这样我们才能使用camera-clibration软件进行校准,最终生成的校准yaml文件是可以在uvc_camera和usb_cam软件包中通用的。
安装uvc_camera的命令如下:
在indigo中安装命令:sudo apt-get install ros-indigo-uvc-camera
在kinetic中安装命令:sudo apt install ros-kinetic-uvc-camera
(2)查看默认的相机信息
首先启动uvc_camera节点,通过如下命令启动,注意需要先启动roscore节点后再启动该节点:
rosrun uvc_camera uvc_camera_node
当启动节点后,查看默认的相机信息,由于目前还没有校准文件的配置信息,因此全部显示为默认值:
(3)准备校准用的棋盘
摄像机的校准是以一个由黑白方块组成的棋盘为基准进行的,如下图所示。可以从本文的附件中下载8x6国际象棋棋盘,并打印出来后将其贴到一个平坦的纸板上。有时也会打印成超过1米的棋盘,但这里用的是A4纸。作为参考,8x6棋盘横向有9个方块,所以有8个交叉点,而竖向有7个方块,有6个交叉点,所以它被称为8x6棋盘。
使用如下命令来进行启动校准节点:
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.0255 image:=/image_raw
下面对命令中各参数进行简单介绍,--size是上述棋盘的宽度和高度, --square 0.0255是棋盘的一个小方格的实际尺寸。这个小方块是正方形,但是打印出来的尺寸可能会各不相同。由于使用A4纸张打印出来是25.5毫米(我们可以使用尺子测量一下每个格子的宽度即可),所以下面命令中写了0.0255,如果换成A3纸张打印的话,每个方格是36毫米,需要将square参数改为0.036即可,一般由于打印的不同大小我们只需要改动square大小,其他参数基本上不用改动。
校准节点运行后会运行GUI,此时如果用相机对准棋盘,校准将立即开始。在GUI屏幕的右侧,可以看到一个标有X、Y、Size和Skew的条形控件。这是校准的进展状态,都以绿色填满意味着校准完成。在校准过程中需要将棋盘对着相机朝着左/右/上/下/前/后移动,还需要倾斜棋盘,这是个比较无聊的过程,我们需要拿着校准棋盘不断的移动,晃荡个大概5分钟左右就差不多了,看到基本上绿色已经填满了。校准所需的所有图像都记录下来之后,CALIBRATE按钮会被激活。点击这个按钮后会进行实际的校准计算,这需要大约3到5分钟。此时就可以将校准板放下了,耐心等待计算完成后,点击SAVE按钮保存校准信息,存储的地址显示在执行校准的终端窗口中,是存储在某一个/tmp目录(如“/tmp/calibrationdata.tar.gz”)中。
接下来将生成的校准文件移动到当前用户的home目录下:
最后只需要打开head_camera.yaml文件修改一下就能保证该校准参数文件正常使用了:
有了校准的配置文件,那以后我们再使用usb_cam打开usb摄像头的话就没有找不到校准文件的警告提示信息了:
0x06 使用rosbag记录日志
当我们在对视频中图像信息流进行处理时经常需要不断的来打开摄像头进行测试,但是这样太过麻烦,而且需要一直插着摄像头,此时我们就可以将相机拍摄的视频保存下来,这样我们可以通过不断的向话题中重发消息就可以模拟有相机的情况了,而且我们还可以将该bag包分发给别人进行测试。
rqt_bag是一个可以将消息进行可视化的GUI工具,ROS日志信息中的rosbag是基于文本的,对于图像数据类的消息管理就需要用rqt_bag了,它可以进行存储、回放和压缩话题消息,而且所有的命令都是基于按钮制作的,所以很容易使用,就跟常用的视频编辑器一样,可以在时间轴上拖拽查看相机图像,下面来详细介绍如何操作:
(1)首先使用roslaunch启动usb_cam节点,使用如下命令启动即可:
roslaunch usb_cam usb_cam-test.launch
(2)使用rosbag来记录指定话题的数据,我这里保存的是压缩图像的话题,这样保存的日志文件很小,方便我们进行调试,使用如下命令开始记录话题输出:
rosbag record /usb_cam/image_raw/compressed
从开始记录日志开始相机现在画面内容都会被录制下来,此时我们就可以在相机前进行各种图像录制,当录制完成后只需要ctrl+c来中断record即可。
(3)接下来准备开始数据回放,首先需要将usb_cam的launch给中断了,不然等下的数据回放话题会跟这个原始的有冲突。要想在rqt中加载bag日志信息,只要在中断中输入rqt选中[插件Plugins]->[日志Logging]->[数据包bag],然后选择坐上方的文件夹图标(Load Bag)加载刚才录制的bag文件即可。
加载刚才保存的bag文件后选中话题,选中Publish后就可以在image_view中看到刚才录制的画面了,如果没有的话可以尝试点击刷新按钮:
0x07 常见问题
1.使用usb_cam无法正常启动相机,建议可以先使用ubuntu系统自带的chesse茄子相机来看看能否正常启动相机,如果系统自带的chesse无法启动相机就考虑是否相机出现问题,例如坏了或者没有插好。
2.在使用usb_cam启动相机时,有的相机无法正常启动需要注意查看相机的输出格式是否为MJPEG格式的,如果是MJPEG的话,此时就需要在自定义的启动相机的launch文件中修改:
0x08 参考文献
[1].ROS WIKI上usb_cam主页[OL]. http://wiki.ros.org/usb_cam
[2].GitHub上usb_cam源码网址[OL]. https://github.com/bosch-ros-pkg/usb_cam.git
[3].表允晳,赵汉哲,郑黎蝹,林泰勋. ROS机器人编程[M]. Seoul(汉城):ROBOTIS Co., Ltd. 2017.12.22:208-214
0x09 问题反馈
大家在按照教程操作过程中有任何问题,可以关注ROS小课堂的官方微信公众号,在公众号中给我发消息反馈问题即可,我基本上每天都会处理公众号中的留言!当然,如果你要是顺便给ROS小课堂打个赏,我也会感激不尽的,打赏30块还会邀请进ROS小课堂的微信群与更多志同道合的小伙伴一起学习和交流!