博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
调试 LenaCV 3D Camera (Linux)
阅读量:2134 次
发布时间:2019-04-30

本文共 5998 字,大约阅读时间需要 19 分钟。

调试 LenaCV 3D Camera (Linux)

<yyhu_live@outlook.com>

2018年5月26日于Carnegie Mellon University

本文的pdf文件可从获取。

1 测试环境

Ubuntu 16.04 LTS, Python 2.7.12, ROS Lunar

本文中“>>> ”表示在Linux终端中输入命令,某些需要sudo权限的命令可能没有写出sudo。

本文使用的双目相机硬件是LenaCV的产品,该产品可以从中国大陆的淘宝网上采购到。

本文由Google Docs在线生成,可能出现某些无法调整的格式问题。

2 基本测试

相机通过USB连接系统后,在Linux中识别该设备

>>> lsusb

显示结果如图所示,其中Device 008即为当前调试的设备。

lsusb结果

安装GTK UVC video viewer. 在接上相机后,运行UVC video viewer,所得画面如所示。通过画面上几个控制滑块控制相机参数以进行调试和测试。LenaCV相机返回的实时画面是一张图,相机内部应当已经完成了同步,并将两个相机的图像进行了拼接。经过实测发现拼接图像的右侧实际上为左摄像头的画面。

使用GTK UVC video viewer直接调试设备

3 ROS libuvc_camera调试

主要调试过程参考了libuvc_camera的官方wiki

3.1 安装libuvc_camera

首先需要确保系统正常安装了ROS,并且ROS处于可以使用状态。

创建一个catkin workspace或者使用已经存在的catkin workspace。切换到catkin workspace的src文件夹,将libuvc_camera的git仓库clone到本地。

>>> git clone https://github.com/ros-drivers/libuvc_ros.git

返回到src文件夹上一级,启动catkin_make进行编译,若报缺少某些库,则直接利用apt-get进行安装即可。

3.2 修改udev rule

根据libuvc_camera官方wiki的描述,使用uvc设备需要拥有一定权限,推荐的做法是针对需要使用的硬件设备添加udev rule。具体做法如下,在/etc/udev/rules.d文件夹下新建文件99-uvc.rules(需要root权限)。这个文件将描述相机的所有者,将所有者设置为当前用户即可。该文件的文件名一般都是以数字开头,其目的是控制文件之间的排序。数字越小,排序越靠前。这样做的道理是Linux系统将在加载硬件驱动的过程中有时会有一些次序要求,用文件名的次序可以控制这些rule加载的先后。99-uvc.rules的内容如所示。

99-uvc.rules

# UVC camerasSUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1e4e", ATTRS{idProduct}=="0568", OWNER="
<用户名>
"

其中OWNER即为需要设置的用户名,这里将其设置为当前用户,idVendor和idProduct直接复制lsusb返回结果中的数值。保存该文件,此后需要将相机重新插拔一次。此后libuvc_camera若不能正常launch,ROS报权限不够错误,处理方法参考3.3节。

3.3 测试libuvc_camera

libuvc_camera定义了一个ros node,名为camera_node,启动这个node一般通过一个launch文件。本测试使用的launch文件内容如所示。

launch file

所示,需要定义几个参数来控制相机,其中width、height、video_mode和frame_rate需要通过v4l2-ctl命令参看,v4l2-ctl需要通过apt-get安装。安装好v4l2-ctl后,执行

>>> v4l2-ctl --list-formats-ext

执行结果如所示。从结果上看相机支持的video_mode包括MJPG,在配置launch file时,需要指定video_mode为mjpeg。图像大小和帧率也需根据中的结果设置。

v4l2-ctl执行结果

启动launch file。

>>> roslaunch <launch file>

首次启动可能由于权限问题而失败,出现如所示画面。此时通过如下命令进行修正

>>> sudo chmod o+w /dev/bus/usb/003/004

其中 003/004 是中报错信息中的部分,请用户根据自己的报错信息进行修改。

权限问题导致启动失败

正确启动时,终端中显示的内容如所示。

libuvc_camera启动消息

... logging to /home/yyhu/.ros/log/2183dccc-5ee1-11e8-8cb9-5800e3fc52bd/roslaunch-airlab-14474.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://airlab:41307/

SUMMARY
========

PARAMETERS
* /camera/mycam/auto_exposure: 3
* /camera/mycam/auto_white_balance: True
* /camera/mycam/brightness: 50
* /camera/mycam/camera_info_url: file:///tmp/cam.yaml
* /camera/mycam/frame_rate: 30
* /camera/mycam/height: 720
* /camera/mycam/index: 0
* /camera/mycam/product: 0x0568
* /camera/mycam/serial:
* /camera/mycam/timestamp_method: start
* /camera/mycam/vendor: 0x1e4e
* /camera/mycam/video_mode: mjpeg
* /camera/mycam/width: 2560
* /rosdistro: lunar
* /rosversion: 1.13.6

NODES
 /camera/
   mycam (libuvc_camera/camera_node)

auto-starting new master
process[master]: started with pid [14484]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 2183dccc-5ee1-11e8-8cb9-5800e3fc52bd
process[rosout-1]: started with pid [14497]
started core service [/rosout]
process[camera/mycam-2]: started with pid [14500]
unsupported descriptor subtype VS_COLORFORMAT
unsupported descriptor subtype VS_COLORFORMAT
unsupported descriptor subtype VS_COLORFORMAT
attempt to claim already-claimed interface 1
Not a JPEG file: starts with 0x68 0x26
Couldn't convert frame to RGB: Unknown error (-99)

正确启动了libuvc_camera后,可以通过ROS的rqt_image_view查看图像,所用到的topic为/camera/image_raw。rqt_image_view的查看结果如所示。

rqt_image_view的查看结果

4 在线双目标定

在线双目标定将利用ROS提供的camera_calibration包实现。

4.1 创建专用publisher

为了能够使用ROS的camera_calibration包,需要将相机的画面从一幅图像拆分为两幅图像,分别对应双目摄像机的两个相机,并且各自发布一个topic。我们需要一个node,订阅libuvc_camera的topic,实时将画面一分为二,并发布两个新的topic。这里将创建一个新的专用publisher完成以上工作。

首先进入catkin workspace的src目录,创建一个新的package,本文中使用的package名称为“lenacv”

>>> catkin_create_pkg lenacv std_msgs rospy roscpp

之后返回到src上一级,使用catkin_make进行初步编译,生成必要的文件。重新执行devel/setup.bash。

>>> source devel/setup.bash

重新回到lenacv的目录,创建scripts目录并进入。编写一个新的ROS node的python文件,内容如所示。这个node名为listen_uvc,并将publish两个新的topic,分别为lenacv_left和lenacv_right。该文件命名为separator.py。

ROS node

请参考Github仓库的最新版本

修改ROS node源码文件的执行权限。

>>> chmod +x separator.py

在外层目录重新执行catkin_make。启动libuvc_camera,之后通过

>>> rosrun lenacv separator.py

来启动刚刚创建的listen_uvc node。启动ROS rqt,添加两个image view的plugin,并各自显示来自lenacv_left和lenacv_right的数据,效果如所示。

拆分后的双目图像

4.2 双目标定

本节主要参考

双目标定使用ROS提供的camera_calibration包。在进行双目标定前,先打印棋盘格标定板。将打印好的标定板平整地固定在某一平面物体表面,利用直尺测量标定板上棋盘格的边长。标定时启动libuvc_camera,启动lenacv_camera的separator.py,最后通过下述命令启动camera_calibration。

>>> rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.0345 right:=/lenacv_camera/right/image_raw left:=/lenacv_camera/left/image_raw right_camera:=/lenacv_camera/right left_camera:=/lenacv_camera/left --no-service-check

此处--size 参数为所用棋盘格的交叉点数量和排布,如所示,圆点所在位置为交叉点。--size参数的第一个数字为交叉点的列数。请确保棋盘格的两个边长方向上的交叉点的数量是不同的,并且保持长边处于水平。--square 参数为棋盘格的边长,单位为m。请确保使用正四边形的棋盘格。

棋盘格

启动后将看到双目的实时灰度图像。通过鼠标调整程序窗口的大小以获得比较清晰的视角。将棋盘格至于双目相机的视野内,确保两个相机都能同时捕捉到清晰完整的棋盘格图像。cameracalibrator.py将自动识别棋盘格,并在识别到第一个棋盘格后,出现“X”、“Y”、“size”和”skew”字样。这些字样下方均有一个类似进度条的标志。移动棋盘格,cameracalibrator.py将自动辨识棋盘格,并在灰度画面上叠加识别到的棋盘格交叉点的彩色图像,如所示。

标定过程中实时识别到的棋盘格

当棋盘格的识别和当前棋盘格的位置符合要求时,cameracalibrator.py有可能将其记录进最终标定数据集。一个棋盘格的输入是否进入最终标定数据集,也取决于棋盘格与相机相对位置在标定数据集中是否已经有类似记录。cameracalibrator.py会试图使记录的数据尽可能的适合用于标定“X”、“Y”、“size”和”skew”并得到更好的效果,它会主动控制数据集数量和范围。每收集到一组棋盘格的有效数据后,终端上会出现提示,如所示,并且上述“X”、“Y”、“size”和”skew”所对应的进度条也会相应增长。

收集棋盘格数据

所示,当数据集收集到了足够的数据,界面上的“Calibrate”按钮将进入使能状态,此时用鼠标点击该按钮开始标定。

使能状态的calibrate按钮

标定可能持续一定时间,此时软件界面可能失去相应,需耐心等待。当标定结束后,终端中将显示标定结果。点击软件界面上的“save”按钮,将标定结果(以及标定数据集)记录在文件系统上。此后可手工复制上述保存好的文件到其他指定位置。注意,保存的数据仅包含两个相机各自的intrinsics,extrinsics仅在屏幕上做出显示,他们所在的位置如所示。手工复制extrinsics,并记录在文件上以留后期使用。

标定得到的extrinsics

转载地址:http://xpugf.baihongyu.com/

你可能感兴趣的文章
行为型模式之模板方法模式(TemplateMethod)
查看>>
行为型模式之访问者模式(Visitor)
查看>>
大小端详解
查看>>
source insight使用方法简介
查看>>
<stdarg.h>头文件的使用
查看>>
C++/C 宏定义(define)中# ## 的含义 宏拼接
查看>>
Git安装配置
查看>>
linux中fork()函数详解
查看>>
C语言字符、字符串操作偏僻函数总结
查看>>
Git的Patch功能
查看>>
分析C语言的声明
查看>>
TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手
查看>>
C结构体、C++结构体、C++类的区别
查看>>
进程和线程的概念、区别和联系
查看>>
CMake 入门实战
查看>>
绑定CPU逻辑核心的利器——taskset
查看>>
Linux下perf性能测试火焰图只显示函数地址不显示函数名的问题
查看>>
c结构体、c++结构体和c++类的区别以及错误纠正
查看>>
Linux下查看根目录各文件内存占用情况
查看>>
A星算法详解(个人认为最详细,最通俗易懂的一个版本)
查看>>