ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

激光雷达与相机联合标定:手动选点、数据采集与时间同步

激光雷达与相机联合标定:手动选点、数据采集与时间同步 上周一个做园区配送小车的老哥给我发了张截图16线激光雷达的点云投到相机画面上近处路沿贴得严丝合缝越往远处越离谱二十米外的楼角整整歪出去半个车身。他一口咬定是相机内参没标好准备重新拿棋盘格折腾一遍。我看了眼那几张叠加图就说先别急这大概率不是内参的事——近处准、远处飞这个特征八成是标定选点时所有点对都挤在同一个高度区间里俯仰和翻滚两个角压根没被约束住。他照着重选了一组高低错落的点重新解算十分钟搞定误差从肉眼可见的几十像素压到三像素以内。类似的事我见过太多次了。激光和相机的联合标定听起来是个高深的数学活实际上大部分翻车都发生在选点和数据采集这两个看起来最没技术含量的环节。而手动标定恰恰是在这些环节里最可控的一条路你亲手决定哪个角、哪根杆、哪个点参与计算错了能立刻定位到具体是哪一对点出了问题。下面这套流程是我自己反复用过、也给同事交接过好几轮的方法从上位机的环境准备一路讲到参数落盘中间会穿插大量只有真踩过才知道的细节。1. 手动标定还没被淘汰它到底解决什么问题现在自动标定工具确实越做越省事无靶标、基于边缘互信息、基于深度连续性的方法一抓一大把很多还带一键优化。但我在实际项目里发现自动方法有个共同前提它假设场景里有足够多、足够规整的几何结构比如笔直的建筑立面、清晰的道路标线、成片的立柱。园区、厂区、高速这类结构化环境没问题可一旦场景换成树丛、堆放杂乱的货物、临时搭建的棚子自动方法的优化就容易跑偏甚至收敛到一个看起来误差很小但物理上完全错误的结果。1.1 三种必须手动介入的现实场景第一种是传感器安装位置特殊。我遇到过把激光雷达装在车顶、相机装在车头保险杠的情况两者基线接近两米还有明显的俯视和侧倾。这种大外参自动标定很难收敛因为视角差异太大同一个物体在两路数据里的形态完全不同互信息这类相似度度量会失效。第二种是验证阶段需要独立证据。自动标定的输出是一个数字你凭什么信它手动标定天然带一组人工确认过的对应点你可以拿它们算重投影残差作为独立的第三方证据。我现在的习惯就是自动标定先跑一遍拿初值再手动挑十来个点验算误差对得上才敢上车。第三种是现场急救。设备在客户那边跑着突然发现标定漂了手边没有标定板、没有标定场地、甚至没有合适的软件这时候能救场的只有手动标定——有一段历史数据包有一张能看清的图像就能干活。1.2 手动、自动、半自动一条务实的选型线我不建议把这三者对立起来它们更像是流水线上的不同工位。我自己的选型逻辑是这样的方法类型适用阶段典型耗时精度量级主要风险纯自动无靶标批量产线、定期复检几分钟中等依赖场景结构场景退化时静默失败自动 靶标出厂标定、精度要求高十几分钟高需要靶标和场地半自动自动初值 手动微调现场部署、返修半小时左右高且可解释依赖操作者经验纯手动选点应急、特殊安装、验证二十分钟到一小时取决于选点质量人为疏漏我个人的主力方案是半自动先用一次快速自动标定拿到初值然后把初值丢进可视化界面手动点几对点做残差检查最后用手动微调把手感不对的自由度掰回来。纯手动从头做的情况主要是没有自动工具可用或者要对自动结果做独立复核。1.3 别混为一谈激光-相机标定和手眼标定、双目标定根本不是一回事这个词经常被人搅在一起。双目相机标定解的是两个相机之间的相对位姿输入是两幅图像上同一特征点的像素坐标输出是相机间的旋转平移同时还顺手把各自的内参和畸变一起标了。手眼标定比如机械臂加相机解的是相机坐标系和机械臂末端或基座坐标系的关系它的核心难点在于机械臂要带动相机做多组不同位姿的运动用多组AxXB形式的方程去解纯靠单次静态观测是解不出来的。而激光-相机标定在这篇文章的语境里是求激光雷达坐标系到相机坐标系的一个固定刚体变换输入是同一物理点在两个坐标系下的坐标——点云里的三维坐标和图像里的二维像素坐标——输出是六自由度的外参。分清这一点非常重要因为它直接决定了你需要什么数据。激光-相机标定不需要机器人做运动不需要多组位姿只要一次静态观测、一组对应点就够了。反过来如果你拿着一套手眼标定的流程去标激光和相机会发现根本没法构造方程。2. 动手前先定死坐标系与数据采集方案标定翻车最隐蔽的原因往往不是算法错了而是两个人在说不同的事。你说外参指的是激光到相机你的同事理解成相机到激光你说y轴向上结果点云里是z轴向上。参数写进文件的时候没人发现跑起来车就往沟里开。所以我把坐标约定放在最前面讲。2.1 六个自由度的现实含义与正负号约定外参就是六个数字三个旋转、三个平移。旋转可以用旋转矩阵、四元数、欧拉角表示平移就是一个三维向量。我强烈建议内部统一用旋转矩阵加平移向量理由是矩阵乘法不会出现欧拉角那种转序不同结果不同的陷阱。只有在跟人交流或者写配置文件的时候才临时转成欧拉角或四元数并且一定要在注释里写清转序。平移向量的物理含义是相机坐标系原点在激光雷达坐标系下的坐标表达如果你存的是激光到相机的话方向正好相反。我自己习惯这样记定义变换 T 把激光系下的点映射到相机系即 p_cam R × p_lidar t。那么 t 就是激光原点在相机系里的位置它的逆变换对应的才是相机光心的位置。注意写 yaml 的时候同一份文件里出现lidar_to_camera和camera_to_lidar两个方向是极其常见的错误来源。我的做法是文件里只留一个方向另一个方向由程序在读取时求逆得到杜绝两头都能写的情况。旋转矩阵的合法性也要顺手检查行列式应该是 1而且 R × Rᵀ 应该接近单位阵。我见过因为手抖写错一个元素导致点云整体被镜像的场景——图像上看着还挺像那么回事但左右是反的这种错误肉眼看叠加图很难发现。2.2 采集一段能标的数据场景、距离、静止与运动数据采集这一步决定了标定的上限。我挑场景的标准有三条有明确的直角结构、有不同高度的物体、有一定的纵深跨度。理想场地是停车场出入口或者厂区转角有墙面提供竖直平面、有地面提供水平面、有立柱或电箱提供竖直边缘和不同高度、有二十米以上的视野纵深。对应点的分布范围我一般控制在五米到三十米之间。太近的点受激光光斑尺寸和相机近场畸变影响大太远的点受激光角分辨率限制——十六线雷达在三十米外相邻线束的垂直间距能到半米以上你根本没法从点云里准确判断某个角点的三维位置。中间这个区间的点三维坐标和像素坐标都相对可靠。静止还是运动这也是个取舍。静止采集最省事不用做去畸变时间戳对齐的压力也小。但如果标定的最终用途是运动中的感知我会额外采一段运动中低速行驶的数据做复验因为这时候才能暴露出那些只在动态下才显现的问题。低速是指十公里每小时以内超过这个速度机械旋转式雷达的点云会被明显拉扯变形。采数据的时候记得把相机的自动曝光、自动白平衡、自动增益全关掉。自动曝光在画面里进出一辆车就会改变亮度虽然不影响几何但你手动点像素的时候对边缘的判读会受影响。而且关掉自动之后图像亮度是固定的后面用同一套参数复验时对比起来更干净。2.3 时间同步从硬触发到软对齐的实际取舍时间不同步的直接表现是静止时标得挺准车一动就整体漂移而且漂移方向和运动方向相关。原因很简单激光点和图像帧根本不是同一时刻的。硬件同步是最干净的方案用同一路触发信号同时驱动相机曝光和雷达旋转起始两路数据带着同源的时间基准。但这需要硬件支持很多改装车上没有。没有硬件同步时退而求其次的做法是软件同步加静止采集——采集时车停稳触发相机抓一帧记录下这一帧的时间戳然后在点云里找时间戳最接近的那一帧中间的时间差控制在十毫秒以内。车停着的时候十毫秒的时间差不会带来任何几何误差。如果必须用运动中的数据那就得做时间对齐把点云按每一条线束的相对时间戳做运动补偿用轮速计或惯性单元的信息把每个点外推到统一时刻。这块工作量和风险都不小我一般建议能静止采集就静止采集把复杂度留到后期。3. 从选点到求解一套可复现的手动标定流程前面铺垫完了这里是正文重点。整套流程可以概括成**在点云里点N个点在图像里点N个对应点把两组坐标丢给求解器看残差不满意就回去重选。**听起来简单但每一步都有讲究。3.1 环境准备与工具盘点我常用的组合是 Ubuntu ROS 环境下的可视化工具加上一个 OpenCV 求解脚本。ROS 这边的好处是点云和图像能同时在一个界面里看选点直观不足是数据要走话题传输偶尔会丢帧所以采集阶段我习惯先用数据包把原始数据录下来标定的时候离线回放可重复性好出问题也能回退。需要的组件大致是点云可视化工具用来显示点云并读取鼠标点击位置的三维坐标、图像查看工具用来读取像素坐标、OpenCV解算和验证、一个小脚本负责把两组坐标合并、求解、输出残差和投影叠加图。相机内参和畸变系数必须在标定之前拿到——这一步用棋盘格或者标定板单独做属于另一个话题但它质量直接决定外参的上限后面会展开说。3.2 在点云里选点的四条硬规矩这是整个流程里最吃经验的部分。我总结成四条第一条点不能共面。如果所有点都落在地面上或者都落在一面墙上那么沿垂直于该平面的方向上的旋转是无法被唯一确定的。经典的PnP问题在共面条件下会出现解的歧义表现就是标定出来的俯仰角或翻滚角偶尔会跳到一个明显不对的值重选几个高度不同的点问题立刻消失。第二条优先选角而不是边优先选竖直缘而不是水平缘。竖直的柱角、电箱的棱、建筑转角在点云里是两条线的交点位置唯一而水平的地面边缘在点云里就是一条带你很难判断该选哪个点。同样竖直边缘在图像上的像素位置比水平边缘更容易判断准因为竖直边缘的检测对图像的横向分辨率更敏感。第三条避免高反光和透明物体。反光膜、水面、玻璃幕墙会让激光出现多路径回波或者直接丢点点云上会出现一片奇怪的散点。这类地方的坐标压根不可信选了就是往数据里掺噪声。第四条避开动态物体和纹理物体。行人、车辆、树叶、草地这些要么位置会变要么边缘模糊到无法定位。我见过有人在点云里选了棵树的树干图像上选了个大概位置结果那棵树被风吹得晃标定结果自然不准。一个实用的做法是**先在点云里选点记下坐标再把点云叠加到图像上用上一次标定的旧参数也行有个大概位置就够从叠加图里去找那个点对应的图像位置。**这比反过来在图像里找点云位置要容易得多因为点云里选中的点可以在图像上打出一个候选标记你只需要在附近做微小修正。3.3 图像端像素坐标的取法与偏差控制像素坐标怎么取直接影响精度。我的一般做法是把图像放大到四倍以上用像素级查看器把边缘放大到能看清灰度过渡然后取过渡带的中点。不要取最亮的一侧也不要取最暗的一侧取中间。这是抵消镜头模糊和边缘扩散最简单有效的办法。取点的数量我建议至少十二对最好十五到二十对。理论上四对不共线的点就能解实
返回列表