任务动机:基于ORB-SLAM3+单目广角摄像头进行二次开发,辅助激光导航实现机器人全局重定位。需要对单目摄像头进行内参和外参标定。

任务描述:
1. 镜头畸变和内参标定
用棋盘格标定

2. 摄像机与机器人坐标系间的位姿标定

  • 在线数据采集:找一个场景内容丰富的环境 启动激光雷达SLAM,启动摄像机图像采集 录制ros bag(最好录制全部,如果空间不够,可以只选激光雷达,摄像机图像,tf) 控制机器人走几圈+走走八字
  • 离线处理:播放bag,启动单目摄像机的ORB-SLAM 保存ORB-SLAM的位姿输出结果和激光雷达SLAM的位姿输出序列(都要有时间戳)
  • 标定:提取相同时刻的ORB-SLAM和激光雷达SLAM的位姿对 计算二者间的位姿关系

1. 引言

标定就是已知标定控制点的世界坐标和像素坐标, 去解算映射关系。一旦这个关系解算出来了,就可以由点的像素坐标去反推它的世界坐标,有了这个世界坐标,就可以进行测量等其他后续操作了。在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定。

相机需要标定的参数通常分为内参和外参两部分。外参确定了相机在某个三维空间中的位置和朝向,至于内参,可以说是相机内部的参数。外参数矩阵可以告诉你现实世界点(世界坐标)是怎样经过旋转和平移,然后落到另一个现实世界点(摄像机坐标)上。内参数矩阵告诉你上述那个点在外参矩阵的基础上,是如何继续经过摄像机的镜头、并通过针孔成像和电子转化而成为像素点的。而畸变矩阵则告诉你为什么上面那个像素点并没有落在理论计算该落在的位置上,还产生了一定的偏移和变形.

本文介绍如何使用Autoware对摄像头进行内参标定,再通过ORB-SLAM对相机和雷达进行联合标定。

2. 镜头畸变与内参标定

ROS官方提供了一个ROS camera_calibration工具包,可以使用它进行内参标定,但是使用下来效果并不好,可能会出现无法保存参数的情况,更推荐使用Autoware,尤其是Autoware还自带了Calibration Toolkit(1.9版本之前,需要在GitHub里面找到之前的版本地址,新的版本取消了),对于激光雷达和相机的联合标定更加友好。Autoware camera_calibration 工具包 与ROS官方的并没有太大区别,可以看作是官方ROS标定工具的一个分支(即ROS Camera Calibration Tools)。

2.1 安装Autoware

官方推荐使用Docker安装,但是为了快捷本文直接源码安装。用Docker的时候要装NVIDIA Docker(因为要用GPU),一牵扯显卡就可能会出问题。建议直接源码编译了一遍Autoware。基于官方的源码安装教程,本文使用的是Ubuntu 16.04 + Kinetic,所以选择了1.12版本,安装方式如下。如果版本不同,需要参考官方教程。

1)安装系统依赖

$ sudo apt-get update
$ sudo apt-get install -y python-catkin-pkg python-rosdep ros-$ROS_DISTRO-catkin gksu
$ sudo apt-get install -y python3-pip python3-colcon-common-extensions python3-setuptools python3-vcstool
$ pip3 install -U setuptools

2)创建工作空间

$ mkdir -p autoware.ai/src
$ cd autoware.ai

3)下载Autoware配置文件

$ wget -O autoware.ai.repos "https://raw.githubusercontent.com/Autoware-AI/autoware.ai/1.12.0/autoware.ai.repos"

4)下载Autoware

$ vcs import src < autoware.ai.repos

5)rosdep安装依赖

$ rosdep update
$ rosdep install -y --from-paths src --ignore-src --rosdistro $ROS_DISTRO (这一步好像会出问题 网上有解决方案)

6)编译工作空间

因为没有安装n卡显卡驱动,所以选择了没有CUDA支持的命令。

$ colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release

可以在文件夹 /autoware.ai/build/ 下面看到 autoware_camera_lidar_calibrator 这个文件夹,这个就是我们要用来做标定的工具包,然后进入到这个文件夹里面的 devel,在devel里面 source 一下 setup.bash。这时候,在终端里输入 rosrun auto, 双击 Tab 键就应该能看到一下命令

$ rosrun autoware_camera_lidar_calibrator

2.2 安装摄像头和发布相关话题

首先检查Ubuntu有没有识别到摄像头,可以在应用程序里面直接打开 Cheese Webcam Booth。这个应用程序是Ubuntu自带的照相机工具,如果显示 No device found,就说明摄像头没有识别成功,还需要查询摄像头的厂商,安装ROS上的驱动。当然,如果是使用双目摄像头的话,可能比较复杂,即使安装好了驱动,也不一定能通过这个程序查看到画面。因为我使用的是单目摄像头,现在大部分的摄像头也都已经是免驱的,插上就可以直接使用。

确定摄像头已经在Ubuntu正确安装之后,关闭Cheese,在终端里输入以下命令来启动摄像头的节点。(注意要先启动 roscore)

$ rosrun usb_cam usb_cam_node

可以通过命令rostopic list看到出现了 /usb_cam/... 等一系列topic

运行 rosrun usb_cam usb_cam_node 之后,这样就确保了单目相机正在通过ROS发布图像,其中我们过会需要使用的是 /usb_cam/image_raw。usb_cam是ROS的一个功能包,如果提示没有找到或无法运行的话,可以参考官方的教程先来安装这个功能。

2.3 标定相机内参与畸变

首先要准备一个已知尺寸的标定板,可以在这里下载。本文使用的是8X6,方块大小为108mm的棋盘标定板。由于标定过程使用的是棋盘内部的角点进行,所以实际上使用的是9X7的棋盘标定板 。

1)启动摄像

$ rosrun usb_cam usb_cam_node

2)启动cameracalibrator.py

$ rosrun autoware_camera_lidar_calibrator cameracalibrator.py --square SQUARE_SIZE --size MxN image:=/image_topic

--square:棋盘格中的每个方格的边长大小,单位为m,实际为 0.108

--size:棋盘格的尺寸是几乘几,注意是inner,也就是出去边长最外圈方格数-1,实际为是8X6。如果这个参数不正确,在标定步骤中会发现标定程序毫无反应

image :发布图像的话题名,实际是 /usb_cam/iamge_raw

修改过的命令如下,当然,使用不同的棋盘格,这些参数也需要改变

$ rosrun autoware_camera_lidar_calibrator cameracalibrator.py --square 0.108 --size 8x6 image:=/usb_cam/image_raw

这里可能会出现打开之后没有相机图像显示的问题,可以在命令后面加上 camera:=/usb_cam --no-service-check,完整命令如下

$ rosrun autoware_camera_lidar_calibrator cameracalibrator.py --square 0.108 --size 8x6 image:=/usb_cam/image_raw camera:=/usb_cam --no-service-check

在上述节点启动起来后,会弹出一个图像框,右边有几个按钮,通过晃动棋盘格使得右边的Calibration按钮变绿。把棋盘格拿到相机前,看到棋盘格上有了mark并且右上方出现了四个滑动条类似的东西,分别表示X、Y、尺度与俯仰,根据提示哪一个自由度完成度不足来移动棋盘格。

Calibration按钮变绿了之后就可以点击一下,命令行窗口会给出计算出的标定结果,这一步窗口可能会变暗,并出现假死状态,需要耐心等待很长一段时间。命令行窗口给出计算出的标定结果后,点击Save按钮即可保存成在home目录下的命名类似于20200811_0036_autoware_camera_calibration.yaml。

打开刚保存的 yaml 文件,可以看到以下内容

YAML:1.0
---
CameraExtrinsicMat: !!opencv-matrixrows: 4cols: 4dt: ddata: [ 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0.,1. ]
CameraMat: !!opencv-matrixrows: 3cols: 3dt: ddata: [ 6.4132780167960482e+02, 0., 4.6321749736436732e+02, 0.,6.4662171134096195e+02, 2.6575705715600145e+02, 0., 0., 1. ]
DistCoeff: !!opencv-matrixrows: 5cols: 1dt: ddata: [ -4.1541156375699345e-01, 2.2717711085658737e-01,-3.9660433213257182e-04, -3.9461694367074014e-03,-7.6117176968176561e-02 ]
ImageSize: [640, 480]
Reprojection Error: 0.0
DistModel: plumb_bob

在这个文件里面,CameraMat: !! opencv-matrix 代表着相机内部的参数,也就是内参。内参是一个3×3的矩阵,形式如下:

A=⎡⎣⎢⎢⎢⎢⎢⎢⎢fx000fy0cxcy1⎤⎦⎥⎥⎥⎥⎥⎥⎥A=[fx0cx0fycy001]

其中,cx和cy表示相机光轴在图像坐标系中的偏移量,以像素为单位。 fx和fy则表示相机的焦距。详解的介绍可以查看这里。DistCoeff: !! opencv-matrix 代表着相机的畸变矩阵,形式如下:

data=[k1,k2,p1,p2,(k3,k4,k5,k6)]data=[k1,k2,p1,p2,(k3,k4,k5,k6)]

注意,括号里的 (k3, k4, k5, k6) 并非是必须存在的参数。k1,k2,k3 ... 是径向畸变系数,p1,p2是切向畸变系数。径向畸变发生在相机坐标系转图像物理坐标系的过程中。而切向畸变是发生在相机制作过程,其是由于感光元平面跟透镜不平行。详解的介绍可以查看这里。因此,根据上述矩阵经过转换之后,可以由之前的 yaml 得到下面的相机参数。

# Camera calibration and distortion parameters (OpenCV)
Camera.fx: 6.4132780167960482e+02
Camera.fy: 6.4662171134096195e+02
Camera.cx: 4.6321749736436732e+02
Camera.cy: 2.6575705715600145e+02Camera.k1: -4.1541156375699345e-01
Camera.k2:  2.2717711085658737e-01
Camera.p1: -3.9660433213257182e-04
Camera.p2: -3.9461694367074014e-03
Camera.k3: -7.6117176968176561e-02
 该参数将在以后用于ORB SLAM 的外参标定使用。

单目摄像头的内外参标定相关推荐

  1. 单目相机的内外参标定

    本教程所使用标定工具为一个9x7的棋盘格,单格尺寸123mm. 内参标定 1.1 借助ROS中的usb_cam功能包,具体实现如下: 安装usb_cam功能包 $ sudo apt-get insta ...

  2. 单目摄像头标定与测距

    单目摄像头标定与测距 一. 标定 首先要对摄像头做标定,具体的公式推导在learning opencv中有详细的解释,这里顺带提一句,这本书虽然确实老,但有些理论.算法类的东西里面还是讲的很不错的,必 ...

  3. python opencv 摄像头标定_(五)单目摄像头标定与畸变矫正(C++,opencv)

    本文将梳理一种单目摄像头标定和矫正的方法,在梳理的过程中,首先使用网上离线的图片数据跑通流程,然后接入自己的camera,手动采集标定图像,实时矫正相机的畸变,然后输出矫正后的图像.全文基于Openc ...

  4. 3D视觉(二):单目摄像头的标定与校正

    3D视觉(二):单目摄像头的标定与校正 文章目录 3D视觉(二):单目摄像头的标定与校正 一.相机模型 1.机器车坐标系到相机坐标系 2.相机坐标系到归一化平面坐标系 3.归一化平面坐标畸变 4.归一 ...

  5. OPENCV3.0 单目摄像头标定(使用官方自带的标定图片)

    OPENCV3.0 单目摄像头标定(使用官方自带的标定图片) 转载于:https://blog.csdn.net/zc850463390zc/article/details/48946855 // o ...

  6. 【机器人原理与实践(二)】单目摄像头标定与单目测距

    文章目录 摄像头标定 4.1 单目相机的建模 4.1.1 图像坐标系到像素坐标系的转换 4.1.2相机坐标系到图像坐标系的转换 4.1.3 合并矩阵 4.2 固定向下摄像头标定 4.3 俯视摄像头标定 ...

  7. 基于matlab的摄像头,基于Matlab的单目摄像头标定

    实验环境:matlab2016 准备材料:单目摄像头.定标板.摄像头拍下定标板的图片 本博客带大家实际动手,再讲单目摄像头标定原理. 准备标定板 标定的开始阶段最需要用到的标定板,可以直接从openc ...

  8. 基于Matlab工具箱进行单目摄像头标定

    实验环境:matlab2016 准备材料:单目摄像头.定标板.摄像头拍下定标板的图片 本博客带大家实际动手,再讲单目摄像头标定原理. 准备标定板 标定的开始阶段最需要用到的标定板,可以直接从openc ...

  9. 基于单目摄像头的BEV实例预测(ICCV 2021)

    作者丨黄浴@知乎 来源丨https://zhuanlan.zhihu.com/p/422992592 编辑丨3D视觉工坊 ICCV'21论文 "FIERY: Future Instance ...

最新文章

  1. 【怎样写代码】工厂三兄弟之工厂方法模式(五):工厂方法模式扩展
  2. 5815. 扣分后的最大得分
  3. 【HDU - 1527】【POJ - 1067】取石子游戏 (威佐夫博弈)
  4. ARM开发步步深入之NandFlash 4KB突围
  5. 设置和开通freebsd远程登录
  6. python 的异常及其处理
  7. Mahout 安装配置及一个简单测试
  8. ROW_NUMBER() OVER的用法
  9. 信号检测与估计理论_永磁同步电机无传感器控制的新策略,提升转子位置检测精度...
  10. 电脑经验小总结(原创)
  11. ffmpeg 踩坑总结 —— 视频转码 转H264格式
  12. 箭头函数写法_JavaScript|箭头函数的用法
  13. java 几种生成海报的方式
  14. 【第三篇:利用ChatGPT编写贪食蛇小游戏】
  15. 2021-04-27 Android 理解frameworks services jni hardware kernel 整个控制过程实例包括回调
  16. LQ0023 三羊献瑞【枚举】
  17. [原创]推荐学习STL的好书(入门级别)
  18. 关于TVS管选型的几个参数 2019-01-19
  19. 作为互联网创业城市的杭州
  20. jstack -l pid:查看线程状态,使用的垃圾回收算法,死锁检测

热门文章

  1. java wait到时间会自动_Java的Object.wait(long)在等待时间过去后会继续往后执行吗
  2. Qt Plugin插件开发指南(1)- 一般开发流程
  3. 机器学习系列7 基于Python的Scikit-learn库构建逻辑回归模型
  4. Python入门程序【六】
  5. 以小见大——那些基于 protobuf 的五花八门的 RPC(3)
  6. 图神经网络在推荐领域,图神经网络的优势
  7. 机器学习 | 斗鱼直播热度影响因素分析
  8. 第五章 多范式的编程语言Scala
  9. 可折叠列表ExpandableList
  10. Aboboo在桌面打不开问题