ARTICLE DETAIL

资讯详情

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

2D激光雷达与相机联合标定全流程:从原理到自动化实操

2D激光雷达与相机联合标定全流程:从原理到自动化实操 做机器人感知和工业视觉这些年2D激光雷达和相机的组合几乎成了最常见的传感器配置而这两个传感器之间的联合标定也成了项目联调阶段绕不开的一关。激光雷达给距离相机给纹理两者一融合AGV能避障、机械臂能抓取、安防设备能做测量。但很多项目一进入联调就开始头疼相机里看到的障碍物边缘投影到雷达坐标系下怎么都对不上目标明明在视野正中间雷达测出来的方向却偏了十几度。问题多半出在外参上也就是两个传感器之间的旋转和平移关系没标定准。联合标定说穿了就是求一组[R|t]把激光雷达坐标系里的点准确映射到相机坐标系里。2D激光雷达与相机的联合标定难的不是原理而是实操雷达只有一条扫描线相机是二维图像两种数据特征差异很大很难像3D点云配3D模型那样直接做特征匹配。下面我会从原理讲到落地用一块棋盘格标定板加一套自动采集与求解脚本把这套流程完整跑通。全程不需要买昂贵的标定设备也不需要手动反复调整角度适合机器人、AGV、工业视觉方向的朋友直接参考。1. 先搞清楚为什么联合标定总让人头疼1.1 传感器融合的前提是坐标对齐2D激光雷达和相机的组合在AGV、移动机器人、工业视觉里太常见了。一个负责测距离、一个负责看纹理正好互补。但融合的前提是两套数据必须在同一个坐标系里对齐。打个比方两个人一个拿测距仪、一个拿望远镜如果两个人的站位和朝向基准不一样报出的目标坐标就互相矛盾最后谁都不敢信。多传感器融合看起来是算法问题本质上首先是坐标系问题。我见过最典型的故障场景AGV上装了2D激光雷达和相机相机检测到前方有行人需要把行人位置换算到雷达坐标系里给导航用。外参没标准时换算出来的位置和雷达实测的位置差了二十多厘米。这个误差在安全避障场景里非常致命。因为雷达测距再准也无法接入相机的语义信息相机识别再准也没法直接把像素坐标转成真实距离。只有外参准确两个传感器的数据才能被正确融合后续的目标检测、避障、定位才能真正联动起来。1.2 手动标定的痛点和自动化标定的优势手动标定听起来简单在图像里点几个点在雷达点云里找对应凑出变换关系。但真正做起来很崩溃。2D雷达数据在图像上投影后是一条曲线没有明显的特征点不同人选的对应特征完全不一样标定结果也千差万别。我早期试过手动微调调了半个多小时看起来勉强重合出门再测又偏了。那种感觉就是“好像标完了但又好像没标完”心里没底。自动化标定的优势在于三个方面可重复、可量化、可批量。可重复是同一套数据任何人跑都会得到同一组外参可量化是标定完能给出残差和验证指标而不是“我觉得对齐了”可批量是产线上每台设备装完都能用同样脚本快速标定不用依赖老师傅感觉。所以自动化联合标定不是炫技是真正能节省时间和减少返工的做法。尤其现在设备出货量大每台都有一定装配公差手动标定一个月能标到怀疑人生。2. 标定原理拆解从坐标系到平面约束2.1 内参、外参和三个坐标系的对应关系联合标定会牵扯三个坐标系激光雷达坐标系、相机坐标系、像素坐标系。2D雷达坐标系原点在雷达旋转中心通常设XL轴朝前、YL轴朝左、ZL轴朝上水平安装时所有点的ZL都为0。相机坐标系原点在光心ZC轴沿镜头光轴朝前。像素坐标系就是图像里的(u,v)坐标是我们最直观接触的平面坐标。相机内参把相机坐标系下的3D点投影成像素公式是 s*[u,v,1]^T K*[XC,YC,ZC]^TK里面主要是焦距fx、fy和光心cx、cy。内参是相机自身的属性和雷达没关系。联合标定要求的是外参也就是雷达坐标系和相机坐标系之间的刚体变换PC R*PL t。R是3x3旋转矩阵t是3维平移向量。把R和t求出来雷达点就能换算到相机坐标系下再通过内参投影到图像上。这里有一个常见的理解偏差把“相机标定”和“联合标定”混为一谈。相机标定是求内参联合标定是求外参。内参标不准外参标完也用不好所以通常内参要事先标好。很多人拿一个没标内参的相机直接做联合标定结果怎么调都别扭其实就是这一步欠了账。2.2 为什么用“平面约束法”解2D雷达与相机外参3D雷达到相机的标定比较常见的做法是拿目标物体在3D点云里找特征点和图像角点对应。但2D雷达只有一条扫描线数据特别稀疏想在图像里找到对应的特征点基本靠运气。所以平面约束法更合适。这个方法的核心思路是利用一块平面标定板同时被两个传感器观测让它们各自观测到的“同一块板”成为约束桥梁。雷达扫描线打在板面上会形成一段直线点集相机通过棋盘格检测能得到标定板平面在相机坐标系下的方程。雷达点经过外参R和t变换到相机坐标系后理论上应该刚好落在板平面上。用数学表达就是对任一雷达点p_l变换后p_c Rp_l t应满足n^Tp_c d 0其中n和d是板平面在相机系下的法向量和常数项。整个标定过程就是通过多帧数据的最小化残差把R和t解出来。这个约束看似简单但有一个关键点2D雷达观测到的是一条线单帧数据对完整6自由度外参的约束并不充分必须采集多个不同姿态的标定板才能把R和t的所有自由度锁死。打个比方一块板你只看一次能知道它面朝哪个方向但不知道相机和雷达相对它有多远换个角度再看几次位置关系才能确定。实际采集至少15组姿态尽量分散后面会专门讲怎么摆。3. 动手前的准备硬件、标定板和采集方案3.1 设备选型与安装细节含FOV与同步雷达这块常见的低成本2D雷达就能用不一定非要上高精度建模雷达。我用过好几款测距噪声差不太多关键是扫描频率稳定、驱动能给出极坐标或直角坐标数据。相机方面选择余地更大工业相机、普通USB相机、深度相机的RGB图都可以参与标定。工业相机的快门和触发更可控适合后面做自动化普通USB相机胜在简单。深度相机我用得也不少比如D435i这类直接用彩色图做标定就行原理不变。镜头焦距会影响视野建议选中等视场角让标定板在画面里占到四分之一以上太小的视场角反而容易让板子出了画面取不到。安装要求只有一条最重要雷达和相机的相对位置一定要固定。外标定完成之后任何微小的机械位移都会让外参失效。所以连接件要刚性好尽量用金属结构件锁紧后最好做个定位标记。雷达扫描平面通常是水平的这个信息后面会用到安装时候尽量用水平仪调平不然后续优化会平白多出不少残差。另外雷达和相机之间的相对朝向不要太极端比如雷达背着相机装标定板无论如何都无法同时覆盖两个视角。FOV重叠和同步也要提前确认。标定板必须同时出现在雷达扫描平面和相机视野里。很多人忽略了雷达扫描平面有固定的高度板放低了雷达扫不到放高了相机又看不到。一个简单验证办法把板拿在手里在不同距离和高度试试看雷达数据里能不能出现连续的线段同时相机画面里板要完整。这个验证不到两分钟能省下后面一小时的排错时间。同步问题分两种情况。板不动的时候雷达和相机差几十毫秒采集都没关系反正板没动。板一旦移动两路数据时间戳对不齐最后标定结果就有偏差。自动化标定最好用软件触发让雷达和相机同时采集或者至少保证采集时板子是静止的放在三角架或夹具上。不要一边晃动板一边采集那样等于给标定数据人为加了噪声。3.2 标定板怎么做才能让雷达和相机都喜欢标定板可以直接买现成的工业标定板也可以自己做。尺寸跟工作距离走3到5米距离下建议A2或A1幅面格子边长30到50毫米格子数量选9x6或11x8这种OpenCV好检测的组合。板子贴底板底板首选铝塑板或亚克力板平整度好。用KT板或者纸箱板的话板面稍微一变形雷达点段的直线拟合和相机位姿估计都会受影响这个坑我踩过。打印一定要用哑光纸不要覆膜。亮面覆膜会在相机图像里形成高光棋盘格角点检测经常翻车。这里有个雷达特有的坑容易被忽略常见2D激光雷达用红外光黑色油墨对红外光吸收很强反射很弱如果板面黑色格子占比太大雷达扫过去会出现丢点或线段断裂的情况。解决办法是尽量让板面以白色为主黑色格子不要做得过大或者干脆用白底加少量特征图案的设计。空有相机标定精度也不行雷达端的稳定性同样决定最终外参质量。如果考虑自动化产线我强烈推荐AprilTag替代棋盘格。AprilTag是单个标签就能精确估计位姿不需要整块棋盘格都可见对遮挡和模糊更鲁棒检测也更快。相机端用apriltag库雷达端还是提取板面的线段。开发和验证阶段用棋盘格比较省事OpenCV原生支持大批量标定场景用AprilTag更稳。当然用AprilTag的话板面尺寸和雷达反射率规律还是一样要遵守不能因为是标签就忽略雷达端。3.3 数据采集的自动化思路和姿态覆盖建议数据采集这一步最值得自动化。手动拍图、手动导数据后期还要检查哪些帧能用效率太低。我习惯写一个脚本循环执行“雷达读一帧、相机拍一帧、分别检测、都成功才保存”的逻辑。雷达端检测到连续直线段相机端检测到棋盘格两者都满足才落盘否则提示操作员调整板的位置和角度。这样做的好处是保存下来的数据几乎每帧都是有效的不用事后花时间筛数据。姿态覆盖比帧数更重要。15到20帧数据里板的位置和朝向要尽量分散前后移动、左右平移、绕竖直轴旋转、轻微俯仰都要来几组。只在一个位置拍20张雷达和相机看到的永远是同一个方向外参的某些自由度根本约束不住。我遇到过标定结果残差很小但外参明显不对的情况原因就是所有帧的板姿态太接近优化陷入了一个“看似正确但实际错误”的解。姿态分散之后这个问题自然消失。自动化采集脚本还可以加一条规则如果连续几帧都不匹配就给出调整提示比如“板靠近一点”“板左右移动一点”“板旋转一点”。实现起来也不复杂通过判断雷达线段点数和相机角点数量就能给出大致方向。这种带引导的采集流程对操作员特别友好产线上随便一个工人都能跑。4. 完整实操从内参标定到外参优化4.1 前置步骤先把相机内参标定好外参标定之前相机内参必须先搞定。内参不准板平面方程就会有系统性误差最后外参怎么优化都救不回来。内参标定可以用OpenCV的calibrateCamera也可以Matlab标定工具箱。我习惯用OpenCV跨平台方便还能把结果存成yaml直接复用。采集时棋盘格要多换位置中心、四角、近处、远处都要覆盖大概20张就够。图像如果过曝或反光角点检测会有误差宁可重拍也不要将就。如果你是深度相机用户比如D435i官方SDK里通常能直接读到出厂内参。但温度变化、镜头微松都会让内参漂移所以条件允许还是自己标一遍更放心。双目相机的话左右目的内参和双目标定都得做好不过联合标定时用其中一个相机的图流程是一样的。内参标定完把fx、fy、cx、cy和畸变系数存好后续solvePnP和投影验证都用这一套参数别每次现算。4.2 雷达数据处理从扫描点提取标定板线段雷达数据处理的目的是从一帧扫描数据里把“标定板上的点”挑出来。2D雷达的输出通常是角度和距离先转成直角坐标angle np.deg2rad(angles) x distances * np.cos(angle) y distances * np.sin(angle) z np.zeros_like(x)转完之后要做几步处理。先滤掉无效点和超远点距离为0或大于设定范围的直接去掉然后按角度排序相邻点距离超过分割阈值就认为是不同目标从而把扫描场景分割成若干聚类最后对每个聚类做直线拟合用RANSAC或最小二乘都行。标定板的截面是直线所以拟合残差小的聚类才有可能是板残差大的聚类大多是墙壁转角或其他曲面。这里有个细节值得说很多初学者只保存线段两端点我建议把所有参与直线拟合的内点都保存下来。优化时用的点越多代价函数对噪声越鲁棒。如果雷达驱动直接输出x,y可以跳过坐标转换直接做聚类和直线提取。分割阈值我一般设10厘米左右这个值要根据场景里物体的密集程度微调太大会把相邻物体并成一个聚类太小会把板子切碎。4.3 相机数据处理检测棋盘格并计算板平面方程相机端要做两件事检测棋盘格计算板平面方程。检测用findChessboardCorners再加上cornerSubPix做亚像素细化。理论上棋盘格只要没被遮挡、亮度正常检测都很稳定。如果偶发漏检一般是反光或板子太小调整一下光照和板的位置就能解决。得到角点后用solvePnP求出棋盘格在相机坐标系下的旋转rvec和平移tvec。这里有个概念棋盘格有自己的一套3D坐标通常z0solvePnP求出的就是这套板坐标系到相机坐标系的变换。板平面方程可以从这个位姿推出来板平面的法向量在相机系下等于板坐标系Z轴的方向也就是旋转矩阵的第三列板平面上的一点就是棋盘格原点在相机系下的位置也就是tvec。一个更稳的替代做法是把棋盘格角点的3D坐标z0全部通过rvec和tvec变换到相机坐标系然后对这些三维点做平面拟合得到法向量n和常数d。这个做法比直接取旋转矩阵第三列平滑能抑制个别角点检测误差。计算时注意符号统一平面方程写成n^Tp d 0那么d -n^Ttvec如果反了点到平面距离的符号就全反了。只要每帧的n和d配对一致优化结果就不受全局符号影响。4.4 外参求解初始化、代价函数与LM优化外参求解我用的是非线性最小二乘。代价函数很直接把每一帧的雷达点通过待求的R和t变换到相机系计算这些点到对应板平面的距离所有帧的残差放一起用Levenberg-Marquardt最小化。def residuals(param, frames): rvec param[:3] tvec param[3:] R, _ cv2.Rodrigues(rvec) total [] for pts_l, n, d in frames: pts_c pts_l R.T tvec dist pts_c n d total.extend(dist.tolist()) return np.array(total) result least_squares(residuals, x0init_param, args(frames,), methodlm)初始化很关键。x0全零只在雷达和相机几乎重合、方向完全一致时能收敛实际安装基本不可能。实操里可以按安装位置估一个大概值比如雷达装在相机右下方15厘米、朝向基本一致就设tvec初值为(0.1, 0.05, 0)rvec初值为(0,0,0)。这个初始值不需要很准但方向要对。优化完成后把旋转向量转成旋转矩阵外参就出来了。优化跑完先别急着用把每帧残差打印出来看看。如果有个别帧残差明显比其他帧大好多倍多半是这一帧雷达线段提取到了板边缘以外或者棋盘格检测有局部误差。直接删掉这几帧重新优化结果通常会更干净。别舍不得删数据保留坏数据只会拉低整体外参精度。5. 踩坑记录常见问题与排查速查表5.1 雷达和相机检测不稳定的原因我整理了实际调试中高频出现的问题直接对照着查就完事。现象可能原因排查与解决雷达提取不到板线段板太小或太远板与雷达扫描平面错开换大板调整板高和俯仰确认重叠FOV雷达线段中间断开黑色区域对红外光反射弱板面不平减少黑格面积哑光打印检查板面平整度相机检测不到棋盘格过曝/逆光/反光板面积太小控制曝光哑光打印让板占画面1/4以上棋盘格偶发漏检板部分出画面或被遮挡调整板位置板完整留在画面内板线段点里有大量外点板后方有近距物体板边缘穿透板后留出空白区域RANSAC拟合排除外点雷达检测不到板的情况在第一次做的时候最多。往往不是雷达坏了而是雷达扫描平面和板没有交点。单线雷达有固定的扫描高度板放低了扫不到放高了相机又取景不到。调整思路是先找到重叠区域再动板。相机能看到的区域比较直观难的是雷达扫描面可以在雷达数据里实时看距离值有没有一个突变的近处小段那就是板。雷达线段断开的坑比较隐蔽。正常白纸板不会断但如果板面用了黑色大面积色块某些角度下雷达会丢点。这不是雷达故障是红外光被黑色表面吸收了。后来我把标定板设计成白底为主黑格比例控制在30%以下问题明显改善。还有一次是板面不平整KT板受潮轻微起拱雷达数据里线段中间的点和两端不在一条直线上残留很大。换铝塑板后立刻好了。5.2 标定结果异常时的排查思路标定跑通了但结果明显不对我最常遇到的是三种情况。第一种初始值跑偏。外参优化是非线性问题初值太离谱会收敛到局部最小输出跟安装关系对不上。排查方法很简单把优化出来的R和t和肉眼安装位置比一比差太远就是初值问题。重新给一个更合理的初始值即可。不要迷信优化器万能给个合理初值能省很多时间。第二种约束不充分。前面说过如果所有帧板姿态一成不变外参某些自由度没被约束优化会输出一个“残差小但实际错”的结果。排查方法是观察优化残差的分布或者用验证集。留几帧不参与优化标定完拿这几帧算残差如果验证残差远超训练残差说明数据重复度高、约束不足。补齐姿态变化重新采集几帧就好。第三种内参不准。这种情况最无解因为外参优化会拼命用错误的内参“找补”最后外参看起来能拟合训练数据但投影到图像上就是对不齐。所以内参一定要在正式标定前自己过一遍别偷懒。相机镜头即使是同一型号个体差异也真实存在换过镜头就必须重新标内参否则联合标定大概率翻车。6. 标定完成之后精度验证与落地经验6.1 三种验证方式残差、投影叠加和交叉验证标定完不能直接收工验证要跟上。第一个验证指标是残差RMS就是优化目标函数里所有点到平面的距离均方根。2D激光雷达本身的测距噪声通常在1到2厘米所以残差RMS小于2厘米基本可用小于1厘米算不错。如果RMS到了四五厘米先别急着怀疑优化器检查内参和雷达数据质量。第二个验证方式是投影叠加最直观。把雷达点通过外参变换到相机系再用内参投影到图像上把点画出来看是否贴合标定板边缘和周围物体轮廓。这个验证能直接暴露外参的微小偏差比如雷达线段比板的实际边缘宽说明平移或旋转某个方向有误差。做这个验证时最好让雷达扫一下周围有明显棱角的物体比如墙角、纸箱边缘对齐效果一眼就能看出来。第三个验证方式是交叉验证。把采集的帧按8比2分训练集和验证集只用训练集优化然后算验证集残差。验证残差和训练残差接近说明数据冗余好、结果可靠验证残差明显偏大说明训练数据姿态覆盖不够需要补拍不同角度的帧。这个方法和深度学习里划分train/validation的思路很像本质都是防过拟合。6.2 如何把标定流程变成可复用的自动化工具整套流程理顺之后完全可以打包成一个工具。相机采集、雷达采集、质量判断、优化求解、报告输出全部写进一个脚本配置好设备参数后一条命令跑完。产线场景里新设备装好之后操作员只需要按提示把标定板摆好脚本会在检测到合格帧后自动保存收满数据就出结果整个过程不用依赖技术人员。落地时还有几个小经验。外参要保存成配置文件程序启动时读取不要每次硬编码。每次标定后把原始数据和报告留档哪天数据对不齐先翻日志看外参和残差有没有异常而不是上来就重新标。最后如果项目里以后要换传感器这套方法可以平移到3D雷达到相机、雷达到IMU的标定上原理相通只是观测数据从“线段”变成了“点面或点集对应”。我自己第一次做联合标定时用KT板贴普通打印纸当标定板雷达线段断断续续相机角点也反光折腾一下午都没标准。后来换成哑光纸贴铝塑板问题当场消失。再后来把采集、筛选、求解都做成脚本过去要按天算的标定工作现在半小时内搞定每台设备还都能留下量化的标定报告。这个思路建议你也试试。
返回列表