自动驾驶视觉融合-相机标定与激光点云投影

Camera Calibration and LIDAR Cloud Projection

多传感器融合一直是自动驾驶领域非常火的名词, 但是如何融合不同传感器的原始数据, 很多人对此都没有清晰的思路. 本文的目标是在KITTI数据集上实现激光雷达和相机的数据融合. 然而激光雷达得到的是3D点云, 而单目相机得到的是2D图像, 如何将3D空间中的点投影到图像平面上, 从而获得激光雷达与图像平面相交的区域, 是本文研究的重点. 其次本文会介绍相机这个大家常见的传感器, 以及讲解如何对相机进行畸变校准.

Github: https://github.com/williamhyin/lidar_to_camera

Email: williamhyin@outlook.com

知乎专栏: 自动驾驶全栈工程师

Camera Technology

针孔相机与透镜

人类最早的相机是针孔相机. 通过在目标物体之间放置一个带有微小开口(针孔)的光栅可以设计一个非常简单的相机. 物体发出的光穿过针孔并落在感光表面上, 该感光表面将光信息存储为图像. 之所以将针孔做得如此之小, 是为了避免由于叠加来自感兴趣对象各个部分的光线而导致图像模糊.

x ′ = f ⋅ x z   y ′ = f ⋅ y z x^{\prime}=f \cdot \frac{x}{z}  y^{\prime}=f \cdot \frac{y}{z} x=fzx y=fzy

基于上述方程, 只需要知道该物体在空间中的3D位置以及相机的焦距, 我们就可以计算出物体在图像平面上的2D位置. (请注意, 生成的坐标x’和y’是公制坐标(m), 而不是像素位置)

但是针孔相机存在透光量很小的问题, 而增大针孔又会导致成像模糊. 解决该问题的一种方法是使用透镜, 透镜能够捕获从感兴趣对象的同一点发出的多束光线. 因此现代相机几乎都使用透镜.

一般情况尺寸适当且位置合适的镜头可折射从空间中的物体上的点P1发出的所有光线, 使它们会聚到在图像平面中单个点p1’. 穿过镜头中心的光线不会发生折射, 它们会一直沿直线直到与像平面相交.

而物体上较近或较远的点却不会聚在图像平面上, 因为它们发出的光线不是会聚在一个点上, 而是会聚在一个半径有限的圆上. 这种模糊的圈子通常称为 circle of confusion (COF). 为了减少模糊, 可以使用光圈, 该光圈是通常可调大小的同心开口, 直接位于镜头后面. 下图说明了原理:

通过减小光圈的直径, 可以阻挡通过外边缘镜头的光线, 从而减小了像平面上COF的大小. 从上图中可以看使用较小的光圈可减少模糊, 但以降低光敏度为代价. 光圈越大, 越多的光线聚焦在图像区域上, 从而使图像更明亮, 信噪比更好.

像平面坐标系到像素坐标系的转换

3D空间中的点在图像平面上的投影与我们在实际的数字图像中看到的并不直接对应, 实际的数字图像由数千个图片像素组成. 因此我们需要实现从图像平面到数字图像上的投影.

在下图中相机中心是O点, 伴随着坐标系i,j,k. 其中k指向图像平面. 与k轴位置相交的C点被称为主点, 代表着图像平面的中心. 以主点为原点的右手平面坐标系o-xy为像平面坐标系.

因此, 在空间上将点P投影到图像平面上之后的第一步是减去主点坐标, 以使离散图像具有其自身的坐标系, 例如该坐标系的中心为图像平面的左下角.

转换过程的第二步是从公制坐标(m)转换为像素坐标. 为此, 我们可以使用校准程序提供的参数kl, 这些参数将将米转换为像素, 并且可以轻松地将其集成到投影方程式中, 如下所示. 请注意, 在像素坐标系中, y轴的原点位于左上角, 并指向下方.

P ⃗ → P ⃗ ′ ( x , y , z ) ⊤ → ( f ⋅ k ⋅ x 2 + c x , f ⋅ l ⋅ y z + c y ) ⊤ [ k , l ] = p i x e l / m \begin{aligned} &\vec{P} \rightarrow \vec{P}^{\prime}\\ &(x, y, z)^{\top} \rightarrow\left(f \cdot k \cdot \frac{x}{2}+c_{x}, f \cdot l \cdot \frac{y}{z}+c_{y}\right)^{\top}\\ &[k, l]=pixel / m \end{aligned} P P (x,y,z)(fk2x+cx,flzy+cy)[k,l]=pixel/m
fk一般在转换矩阵中称为alpha, fl称为beta.

相机校准(camera calibration)

使用镜头虽然可以像针孔相机一样计算空间中的3D点通过镜头后在图像平面上的2D位置, 但是大部分镜头会将失真引入图像. 最常见的是变形称为“radial distortion”, 这是由于镜头的焦距在其直径上不一致. 一般情况镜头的放大效果根据相机中心(光轴)和通过镜头的光线之间的距离而变化. 如果放大倍数增加, 则产生的失真效果称为“pin cushion distortion”. 如果减小, 则称为“barrel distortion”. 使用广角镜如GOPRO时, 通常会发生” Barrel distortions“.

请记住, 如果我们需要通过图像得出关于目标物体(例如车辆)的空间位置, 一定要对相机进行畸变校准(calibration). 通常, 这是通过拍摄一组平面棋盘图案的图片来完成的, 可以从这些对象的已知几何形状中可靠地导出所有镜头和图像传感器参数. 消除相机图像失真的过程称为校正(rectification).

网上有很多关于如何使用OPENCV对相机进行畸变校准的教程, 我给大家推荐OPENCV官方的教程PYTHON, C++.

但是我最建议的方式是通过MATLAB的神器tools Camera Calibrator来进行畸变校准, 非常的高效和迅速, 不需要自己编码, 而且能直观的看到校正前后的图像变化. 这是MATLAB的校准教程.

请注意得到相机内参畸变参数的过程是畸变校准(calibration), 拿着相机内参和畸变参数去消除相机图像失真的才叫校正(rectification). 下文的KITTI数据集已经给出了相机内参和畸变参数, 因此不需要再去拍棋牌图校准了.

在得到相机内参畸变参数后可以通过OPENCV函数直接对图像进行校正, 你不需要了解复杂的公式.

畸变参数:注意有的文章中还会出现k4,k5,k6, 这三个参数基本用不到, 可以忽略.
 Distortion coefficients  = ( k 1 k 2 p 1 p 2 k 3 ) \text { Distortion coefficients }=\left(\mathrm{k}_{1} \mathrm{k}_{2} \mathrm{p}_{1} \mathrm{p}_{2} \mathrm{k}_{3}\right)  Distortion coefficients =(k1k2p1p2k3)
基于PYTHON OPENCV 的畸变校准和校正可以遵循如下步骤:

// Converting an image, imported by cv2 or the glob API, to grayscale:
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
// ret, corners = cv2.findChessboardCorners(gray, (8,6), None)
ret, corners = cv2.findChessboardCorners(gray, (8,6), None)
// Drawing detected corners on an image:
img = cv2.drawChessboardCorners(img, (8,6), corners, ret)
// Camera calibration, given object points, image points, and the shape of the grayscale image
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
// Undistorting a test image
dst = cv2.undistort(img, mtx, dist, None, mtx)

而c++代码相对复杂, 在实际校正这一块, 首先调用 cv: : initundistortcorrectfymap 来查找转换矩阵, 然后使用 cv: : : remap 函数执行转换. 详情看上文中的教程链接.

CMOS 相机

CMOS (Complementary Metal-oxide Semiconductor)技术具有几个优点:与CCD(Charge-Coupled Device)不同, CMOS芯片集成了放大器和A / D转换器, 这带来了巨大的成本优势. 对于CCD, 这些组件位于芯片外部. CMOS传感器还具有更快的数据读取速度, 更低的功耗, 更高的抗噪能力以及更小的系统尺寸. 由于这些优点, 在汽车应用中, 几乎所有相机都使用CMOS传感器.

值得注意的是对于自动驾驶汽车的相机, 分辨率实际上并不是那么重要, 目前大部分汽车相机像素在1百万到8百万像素这个区间内, 相对于手机动辄1亿的像素小的不能再小了. 对于汽车相机重要的是感光度, 因为像素量越小, 像素面积越大, 意味着更多的光子落入一个像素, 具有更好的弱光可见性.

LIDAR Cloud Projection

齐次坐标系

在开始激光点云投影前, 首先我们得讨论什么是齐次坐标. 齐次坐标是指一个用于投影几何里的坐标系统, 如同欧几里得坐标系一样. 那我们为什么需要齐次坐标呢?欧几里得坐标系不是很好吗?

上文提过, 在相机世界中, 3D外界点转换到2D图像像素点转换方程是
p ⃗ = [ x y z ] → p ⃗ ′ = [ α x z + c x β y z + c y ] \vec{p}=\left[\begin{array}{l} x \\ y \\ z \end{array}\right] \rightarrow \vec{p}^{\prime}=\left[\begin{array}{c} \alpha \frac{x}{z}+c_{x} \\ \beta \frac{y}{z}+c_{y} \end{array}\right] p

  • 15
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
随着自动驾驶技术的不断发展,多模态感知成为了实现自动驾驶的关键技术之一。激光雷达和相机是自动驾驶中最常用的两种传感器,它们分别具有高精度测距和高分辨率成像的特点。如何将激光雷达和相机的信息融合起来,实现更加全面、准确的环境感知,成为了研究的热点。 面向自动驾驶多模态感知的激光雷达-相机融合框架主要包括以下几个步骤: 1. 数据预处理:对激光雷达和相机采集到的数据进行预处理,包括去噪、校准、配准等操作,以确保数据的准确性和一致性。 2. 特征提取:对激光雷达和相机数据进行特征提取,提取出各自的特征信息。激光雷达可以提取出点云数据,相机可以提取出图像特征点、颜色等信息。 3. 特征融合:将激光雷达和相机提取出的特征融合起来,形成一个多模态感知的环境模型。常用的融合方法包括点云-图像投影融合、特征点匹配融合等。 4. 目标检测与跟踪:利用融合后的环境模型,进行目标检测与跟踪。可以利用深度学习等方法进行目标检测,利用卡尔曼滤波等方法进行目标跟踪。 5. 场景分割与建图:根据融合后的环境模型,对环境进行场景分割,将场景分成不同的区域,同进行三维建图,建立起环境模型。 6. 路径规划与控制:基于环境模型和目标检测结果,进行路径规划与控制,实现自动驾驶。 总之,面向自动驾驶多模态感知的激光雷达-相机融合框架可以有效提高自动驾驶系统的环境感知能力,为实现自动驾驶提供更加可靠、安全的技术支持。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值