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

本文介绍了自动驾驶中多传感器融合的关键——激光雷达和相机数据的融合,特别是如何将3D激光点云投影到2D图像平面上。首先,文章阐述了相机技术,包括针孔相机模型、像平面坐标系到像素坐标系的转换以及相机校准过程。接着,讨论了齐次坐标系在激光点云投影中的作用,以及内外参矩阵在3D到2D投影中的应用。最后,以KITTI数据集为例,解释了如何利用相机内参和外参实现激光雷达点云到图像的投影,并提供了相关工具和资源链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<think>好的,我现在需要回答用户关于激光雷达相机联合标定的技术资料和实现方法的查询。首先,我要回顾用户提供的引用内容,确保准确引用相关信息。用户提到的四个引用涉及标定流程、现有框架、数据采集转换以及MATLAB的实现方法。接下来,我需要将这些信息整合成一个结构清晰的回答,同时遵循系统级指令中的格式要求,比如行内数学表达式用$...$,独立公式用$$...$$,并生成相关问题。 首先,我应该概述联合标定的基本概念和目的,引用[1]提到了使用棋盘格作为标定对象,提取角和平面,建立几何关系。这里可能需要解释坐标系的转换,涉及旋转矩阵$R$和平移向量$t$,比如刚体变换公式:$$P_c = R \cdot P_l + t$$,其中$P_c$和$P_l$分别是相机和激光雷达坐标系中的点。需要确保正确使用LaTeX格式。 然后,按照步骤分点说明实现方法。例如,第一步是传感器数据采集,引用[3]提到启动驱动并录制话题数据,使用rosbag记录点和图像。第二步是特征提取,引用[1]和[4]指出需要从图像中提取棋盘角点,从点中提取平面,这里可能需要涉及角点检测的算法,比如Harris角点检测,或者使用OpenCV的函数如findChessboardCorners。数学上,角点的坐标可以用像素坐标$(u, v)$表示,而点中的平面方程可能表示为$ax + by + cz + d = 0$,需要正确使用行内公式格式。 第三步是坐标系对齐,需要建立两个坐标系之间的对应关系。这里可能需要使用最小二乘法或SVD分解来求解最优的$R$和$t$。例如,目标函数可能是最小化重投影误差,即$$\min_{R,t} \sum_{i=1}^n ||p_i - K(R P_i + t)||^2$$,其中$K$是相机内参矩阵,$p_i$是图像中的点,$P_i$是激光雷达点。这个公式应作为独立公式处理,使用$$...$$。 第四步是标定工具,引用[2]提到Autoware、Apollo等框架,但需要注意品牌兼容性。引用[4]提到MATLAB的实现方法,可能需要调用计算机视觉和点处理工具箱的函数。 接下来是技术难点,比如时间同步、传感器分辨率差异、特征匹配精度等。需要引用[3]关于数据同步的问题,可能提到时间戳同步或硬件触发的方法。 最后,生成相关问题需要考虑用户可能的后续疑问,比如标定精度评估、多传感器标定、实时标定方法等,确保问题主题相关且具有延伸性。 在整理过程中,要确保所有数学表达式正确使用LaTeX格式,中文回答结构清晰,分步骤说明,并正确标注引用。同时检查是否存在格式错误,如行内公式是否用$包围,独立公式是否单独成段,引用标识是否在段落末尾自然添加。</think>### 激光雷达相机联合标定技术及实现方法 激光雷达相机联合标定(Lidar-Camera Calibration)的核心目标是建立两者坐标系之间的几何映射关系,实现多模态数据的精确对齐。标定过程通常基于棋盘格等标定板,通过提取传感器数据中的特征点或平面,求解旋转矩阵$R$和平移向量$t$,满足刚体变换公式: $$P_c = R \cdot P_l + t$$ 其中$P_c$和$P_l$分别表示目标在相机和激光雷达坐标系中的坐标[^1]。 --- #### **实现步骤** 1. **传感器数据采集** - 同时录制激光雷达点(如话题`/rslidar_points`)和相机图像(如`/usb_cam/image_raw`),使用ROS工具`rosbag record`保存为`.bag`文件[^3]。 - 将`.bag`文件转换为点文件(`.pcd`)和图像文件(`.png`),便于后续处理[^4]。 2. **特征提取** - **相机端**:通过棋盘格角点检测(如OpenCV的`findChessboardCorners`)获取像素坐标$(u, v)$,结合相机内参矩阵$K$计算角点的三维相机坐标系坐标[^1]。 - **激光雷达端**:从点中提取棋盘格平面(如RANSAC平面拟合),计算平面方程$ax + by + cz + d = 0$,并提取角点坐标[^1]。 3. **坐标系对齐** - 建立特征点对应关系,通过最小二乘法或奇异值分解(SVD)求解最优的$R$和$t$,使重投影误差最小: $$\min_{R,t} \sum_{i=1}^n ||p_i - K(R P_i + t)||^2$$ 其中$p_i$为图像中的角点,$P_i$为对应的激光雷达点[^1]。 4. **标定工具框架** - 常用工具包括MATLAB(点图像处理工具箱)、Autoware和Apollo框架,但需注意传感器型号的兼容性[^2][^4]。 --- #### **技术难点** 1. **时间同步**:需保证激光雷达和相机数据的时间戳对齐,可通过硬件触发或软件插值实现。 2. **特征匹配精度**:点分辨率低时,平面提取易受噪声干扰,需结合滤波算法(如统计离群点移除)[^1]。 3. **非线性优化**:标定参数可能需进一步通过Levenberg-Marquardt算法优化,以减小累积误差[^4]。 --- #### **典型应用场景** - 自动驾驶:多传感器融合的目标检测跟踪。 - 机器人导航:环境三维重建语义信息融合- 工业检测:高精度测量缺陷识别。 ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值