尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

多标定板图像如何用原图复制+遮挡法搞定Kalibr内参标定

多标定板图像如何用原图复制+遮挡法搞定Kalibr内参标定 做相机标定的人多少都碰过这种场面采集回来的数据打开一看画面里摆了9块棋盘格标定板拍得还挺满。用Kalibr标相机内参直接喂原图检测漏板、角点错乱、焦距跑飞问题一个接一个。我前阵子就遇到这么一批数据折腾下来发现根本不用改Kalibr源码用“原图复制 遮挡”的办法就能把内参标好重投影误差稳定在0.15像素左右整个过程只写了一个几十行的Python脚本。这篇文章就把这个方案的原理、代码和踩过的坑完整梳理一遍给同样被多标定板图像折磨过的朋友做个参考。1. 问题是怎么来的多标定板场景并不少见1.1 什么时候会拍到“一张图9块板”很多做视觉的人第一反应是好端端的为什么要在一张图里放9块标定板这不是给自己找麻烦吗但实际工程里这种数据出现的频率比想象中高得多。最常见的是多相机产线标定场景。为了提高效率工程师会把9块板子同时架在视野的不同位置让多个相机同时对着这个布满板子的区域采集一帧。这样做的目的很直接一次快门所有相机都能拍到足够多的标定特征省去了逐相机摆放板子的时间。在机械臂抓取、AGV避障这类需要多个相机共同覆盖大视场的项目里这种“一帧多板”的采集方式几乎是标配。另一种常见情况是标定板不够大但视场角落畸变又必须标出来。单块板子放在视野中央边缘畸变几乎没有足够的角点约束放大了板子又超出画面。于是有人把几块小板子拼在一起铺满视场保证画面中心和四个角落都有棋盘格。这种“拼板”采集方式本质上就是用多块板子去覆盖单块大板子覆盖不了的区域。还有一种是采集时没注意环境。比如标定柜子旁边刚好有块镜子或者地面上铺了带棋盘格图案的地砖画面里莫名其妙就出现了第二块、第三块“板子”。这种误入画面的情况虽然不常见但一旦出现Kalibr往往会在这些干扰图案上浪费大量计算资源最后给你一个莫名其妙的结果。不管你是有意还是无意拍到了多块板子只要画面里同时存在两块以上的完整标定板Kalibr的标准流程就开始变得不可靠了。1.2 拿Kalibr直接跑会出什么妖我拿这批9板数据直接跑了kalibr_calibrate_cameras现象非常典型。第一次跑它在检测阶段就一直在刷警告提示某帧图像检测到的角点数量异常。打开ROS bag可视化看了一眼Kalibr在9块板子上随机选了一块来检测下一帧又跳到另一块角点坐标在不同板子之间来回横跳。这直接导致特征点跟踪失效优化后相机内参里的焦距变成了负值——对你没看错焦距是负的这种结果一眼就能看出是特征点对应关系整个乱掉了。有时候它也能勉强“检测成功”但仔细看标定结果重投影误差到了5像素以上畸变系数大得离谱。原因是Kalibr的棋盘格检测器默认画面里只存在一个完整的棋盘格输入包含多块板的图像时它会优先选择一个最大的棋盘格区域剩下来的板子就成了背景。这种部分信息参与优化的结果等于用残缺数据去拟合一个高维模型数学上能找到解但解没有物理意义。我也试过用图像裁剪的方式把原始大图切成9块小图每块只包含一块标定板然后再输入给Kalibr。这个思路乍一看和“遮挡”类似但实际上有一个致命问题裁剪改变了图像的尺寸和像素坐标原点而相机内参里的主点坐标、畸变模型都建立在原始图像坐标系下。裁剪后的中心点不再是原始图像的光心标定出来的内参基本不能用除非你后续做一套坐标映射来补偿但那已经偏离“直接标好”的初衷了。所以最理想的方案是保持原始图像尺寸不变保持原始图像坐标系不变只屏蔽掉不想要的标定板让Kalibr在每一张图里“看到”且只“看到”一块板子。2. 方案原理为什么“原图复制遮挡”能骗过Kalibr2.1 Kalibr的内参标定到底在算什么要理解这个方案为什么有效得先搞清楚Kalibr标定内参的数学本质。Kalibr做内参标定时本质上在优化一组参数相机内参K焦距、主点、畸变系数D以及每帧图像对应的相机外参T旋转和平移。它的目标是让“三维空间中标定板的角点”通过“当前估计的内参外参”投影到图像平面后和“图像上检测到的角点像素坐标”之间的重投影误差最小。这个优化过程有两个关键输入一是图像上检测到的角点像素坐标二是标定板本身的物理尺寸。对于后者Kalibr通过你提供的target配置比如棋盘格的行列数和方格大小来建立三维点集。在检测阶段Kalibr调用OpenCV的棋盘格检测器在每帧图像里寻找角点网格。OpenCV的检测器基于黑白格点阵的梯度变化来定位角点它天然假设画面里只有一个棋盘格。当画面里出现9块棋盘格时检测器要么找到其中一块并忽略其余要么在多个候选棋盘格之间产生跳变。一旦不同帧之间检测到的棋盘格不一致优化时使用的角点对应关系就崩了——有的角点来自左下角板子有的来自右上角板子这些点在三维空间中根本不属于同一个标定板平面强行放到同一个残差项里去优化结果必然发散。而Kalibr在优化时同一台相机的所有帧共享同一组内参K和D。也就是说不管画面里是哪块板子只要角点检测正确所有观测都在约束同一个K和D。这就是“原图复制遮挡”方案的数学基础把多板图像拆成多份单板图像让每一份图像只保留一块标定板其余全部变成无效黑色区域。这样Kalibr检测器在每份图像里只会找到唯一一块板子角点对应关系不会混乱。而因为图像尺寸没有变像素坐标还是原始坐标系下的坐标所以标定出来的内参直接就是原始相机的内参。2.2 复制遮挡为什么有效举个直观的例子。假设你有一张1920x1080的图里面9块板子分布在9个不同区域。原图复制遮挡的做法是把这张图复制成9份第1份保留左上角那块板其余8块板的位置全部填成黑色第2份保留正上方那块板其余板的位置全部填成黑色以此类推。由于纯黑色区域没有任何角点特征OpenCV的棋盘格检测器在每份图像里都只能定位到唯一一个棋盘格。Kalibr会把这9份图像当成一个相机拍摄的9个不同观测。但这些观测共享同一个内参K和D且图像尺寸和原图一致所以优化出来的内参等价于用原始完整图像中的9块板子同时做约束。这就像考试时把一道有9个小问的大题拆成9道小题虽然不是同一道题但考察的是同一个学生的知识水平。Kalibr对相机内参的估计也是同一个道理——每块板子提供的角点都在约束同一个相机模型板子之间互不干扰但都在为同一个K和D投票。更重要的是多块板子同时分布在画面不同区域对角点边缘畸变的约束能力比单块板子强得多。单块板子放在画面中央只约束了中心区域的畸变9块板子铺满画面中心和四角都有角点畸变参数被约束得很充分。这也是为什么这个方案标完之后重投影误差反而可能比传统单板标定更低。2.3 为什么选复制遮挡而不是改源码很多人遇到这种情况第一反应是改Kalibr源码让它支持多板检测。我个人的看法是除非你是Kalibr的维护者或者你有大把时间可以花在这个标定任务上否则改源码是非常不明智的选择。Kalibr是用C写的改它的角点检测逻辑涉及OpenCV检测器的底层调用、多目标管理和帧间特征关联改完还得自己重新编译整个标定工具链。哪怕你只改几行代码从修改到验证半天时间就没了。而且Kalibr的CMake配置依赖一大堆库换台机器可能就得重新折腾半天环境。对于大多数工程师来说标定只是项目里的一个环节不是核心研发任务时间成本完全划不来。改数据不改工具是更稳妥的思路。我们只需要在数据准备阶段做处理标定工具本身跑的还是官方版本行为可预期出了任何问题也好定位。而且这个“复制遮挡”的Python脚本写完之后可以反复复用下次再遇到多板数据改一下路径就能跑。改源码则是这次改了下次还得继续维护性价比完全不在一个量级。我做这个方案的时候从写脚本到最后标定完成总共花了一个多小时。其中大部分时间还是花在检查板子自动检测的准确性上。如果让我去改Kalibr源码以我的C能力估计没个一两天根本下不来。3. 实操把9块板的单帧变成可标定的数据序列3.1 准备阶段确认标定板参数和采集要求在动手写脚本之前先把两件事确认清楚。第一标定板的物理参数必须精确。以棋盘格为例需要知道两个关键数字内角点的行数和列数以及每个方格的实际边长。注意内角点是黑白方块交接处的点不是棋盘格的格子数。一张标准棋盘格如果是12x9个格子那么内角点就是11x8个。这个数字填错哪怕一个标定出来的焦距就是错的。我建议拿到一块板子之后先亲手数一遍格子再拿尺子量一下方格边长不要直接相信标定板的规格说明书因为有些便宜板子的实际打印尺寸和标注有出入。第二采集时的相机设置需要固定。标定过程中相机的焦距、光圈、曝光时间都要锁死绝对不能开自动曝光或者自动对焦。自动曝光会导致遮挡后的黑色区域占比太大时相机自动调高增益或者曝光时间让被保留的标定板区域过曝甚至全白角点直接消失。很多人标定失败就是因为忘了关自动曝光。采集时还要保证板子在空间中的姿态丰富。不要只平行对着相机拍要包含俯仰角、偏航角、滚动角的变化。理想情况下每一帧画面里9块板子都清晰可见且相机在空间中处于不同位置和角度。拍摄30到60组这样的多板图像就够了。3.2 自动检测每块标定板的位置拿到一批图像后首先需要知道每块板子在图像里的像素区域。如果只有几张图可以手动用cv2.selectROI框选9块板子也就十几分钟。但通常我们会有一批甚至几百帧图像手动框选就不现实了。我用的是基于轮廓检测的自动定位方案整体思路如下对图像做灰度化和高斯模糊用自适应阈值生成二值图再查找轮廓。标定板在图像中通常是面积最大的几个四边形区域所以用approxPolyDP把轮廓拟合成多边形筛选出面积在合理范围、并且恰好是四边形的轮廓。对每个候选四边形裁下它的包围盒在这个ROI里调用cv2.findChessboardCorners如果能检测到棋盘格角点就说明这个区域确实是一块标定板。这个方法对光照有一定要求。如果9块板子亮度差异很大或者部分板子被阴影遮挡自适应阈值可能分裂出错误的轮廓。我在实际处理时给findChessboardCorners加上了CALIB_CB_ADAPTIVE_THRESH和CALIB_CB_NORMALIZE_IMAGE标志明显提高了命中率。如果某些帧自动检测失败再退回去用脚本输出每块候选区域的截图人工确认是哪一步出了问题。不过我也遇到过轮廓查找把两块相邻板子当成一个整体的问题。如果两块板子的方格间空隙太小二值化后它们的黑色区域会连成一片拟合出来的四边形会把两块板子包在一起。这种情况下findChessboardCorners大概率检测失败因为检测到的角点数量不是标准棋盘格的角点数。此时我会在二值图上做一次腐蚀操作把相邻板子之间的连接断开然后再查轮廓基本能解决。3.3 生成遮挡副本的核心代码下面给出我实际使用的遮挡生成脚本。这段代码的逻辑是读入一组原始图像对每张图自动检测所有板子的包围盒然后为每块板子生成一份遮挡副本输出到一个独立目录。import cv2 import numpy as np import os import glob CHESSBOARD_SIZE (11, 8) # 内角点行列数按实际板子改 SQUARE_SIZE 0.03 # 方格边长米按实际板子改 MIN_AREA 5000 # 最小轮廓面积过滤噪声 BORDER_PAD 12 # 保留区域向外扩展的像素数避免裁太紧 def find_board_rects(img): gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur cv2.GaussianBlur(gray, (5, 5), 0) binary cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) rects [] for cnt in contours: area cv2.contourArea(cnt) if area MIN_AREA: continue peri cv2.arcLength(cnt, True) approx cv2.approxPolyDP(cnt, 0.02 * peri, True) if len(approx) ! 4: continue x, y, w, h cv2.boundingRect(approx) roi gray[y:yh, x:xw] ret, _ cv2.findChessboardCorners(roi, CHESSBOARD_SIZE, cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_NORMALIZE_IMAGE) if ret: rects.append((x, y, w, h)) return rects def make_masked_copies(img, rects, frame_idx): h, w img.shape[:2] copies [] for i, (x, y, bw, bh) in enumerate(rects): mask np.zeros((h, w, 3), dtypenp.uint8) x0 max(0, x - BORDER_PAD) y0 max(0, y - BORDER_PAD) x1 min(w, x bw BORDER_PAD) y1 min(h, y bh BORDER_PAD) mask[y0:y1, x0:x1] img[y0:y1, x0:x1] output_name fframe_{frame_idx:04d}_board_{i:02d}.png copies.append((output_name, mask)) return copies # 主流程遍历原始图像目录 raw_dir ./raw_frames out_dir ./masked_frames os.makedirs(out_dir, exist_okTrue) for path in sorted(glob.glob(os.path.join(raw_dir, *.png))): img cv2.imread(path) frame_idx int(os.path.splitext(os.path.basename(path))[0]) rects find_board_rects(img) print(f{path}: 检测到 {len(rects)} 块板子) for output_name, mask_img in make_masked_copies(img, rects, frame_idx): cv2.imwrite(os.path.join(out_dir, output_name), mask_img)这段代码有两个细节值得说明。第一个细节是BORDER_PAD。遮挡区域不能刚好裁到板子的边缘因为棋盘格最外圈的黑色方块和纯黑背景之间如果没有过渡检测器可能把边缘误判为角点网格的一部分。我向外扩了12个像素既保留了板子周围的一小圈原始纹理又不会把相邻板子带进来。第二个细节是输出文件的命名方式。frame_编号_board_编号.png这个命名顺序很关键。如果你按自然顺序排列同一帧的9份副本是连续相邻的Kalibr在整个序列上检测时会在连续9张几乎相同姿态的图之间反复优化外参。为了降低这种影响我在后续构建bag时手动打乱了图像顺序保证相邻两帧尽可能来自不同的空间姿态。这一步对结果的稳定性很有帮助。3.4 生成图像序列和启动标定遮挡副本生成之后有两种方式喂给Kalibr。一种是直接把图像序列做成ROS bag另一种是用Kalibr支持的单目图像数据集。我用的是ROS bag方式因为Kalibr对bag的处理更成熟。制作bag时需要注意一点这9份副本虽然内容来自同一张原始图像但在bag里应被视为同一台相机在不同时刻拍摄的帧。我给每份副本分配不同的时间戳时间戳之间的间隔保持一致比如0.05秒然后全部发布到同一个图像topic下。这样Kalibr看到的是一段图像序列每个时刻只有一块板子可见但整段序列覆盖了9块板子的所有位置信息。制作用户的bag工具不唯一我用的是rosbagcv_bridge方式代码量也不大。核心思路就三步读取遮挡副本目录循环将每张图像转成sensor_msgs/Image消息以固定时间间隔发布到/cam0/image_raw话题。bag做好之后再写一个标定板的target配置文件。注意所有9块板子必须是同一规格因为Kalibr的target配置只支持单一标定板类型。如果混用不同尺寸或行列数的板子这个方案就失效了。target_type: checkerboard targetCols: 11 targetRows: 8 sizeMeter: 0.03一切就绪后执行标定命令kalibr_calibrate_cameras \ --bag multi_board.bag \ --topics /cam0/image_raw \ --models pinhole-radtan \ --target checkerboard.yaml这里我选择的相机模型是pinhole-radtan。如果你的相机是鱼眼可以换成pinhole-equi或omni-radtan根据实际镜头类型来定。跑完之后Kalibr会输出内参、畸变系数以及重投影误差的统计结果。我跑完的结果重投影误差0.14到0.18像素畸变系数分布合理说明这个方法在数学上是自洽的。4. 踩坑记录与排查速查表4.1 九块板只检测到五块的排查第一次跑自动检测脚本我的9块板子只检测出了5块。排查下来发现了三种原因。第一种是轮廓面积阈值设置过高。有一块板子在画面中面积偏小被MIN_AREA给过滤掉了。这种情况把阈值下调一个量级或者改成按图像总面积的比例来计算阈值就能解决。第二种是自适应阈值在处理光照不均时失效。画面里有一块板子正好处在阴影边缘二值化后棋盘格的白色方块和背景融为一体找不到完整的四边形轮廓。我的处理办法是调整blockSize参数从11改成15同时对图像做一次cv2.equalizeHist直方图均衡化再跑一遍轮廓检测那块板子就出来了。第三种是最隐蔽的两块板子在二值图上连通。这发生在两块板子距离很近且方格大小相近的情况下。腐蚀膨胀之后连通区域断开检测恢复。所以我在实际脚本里加入了cv2.erode和cv2.dilate的预处理步骤对二值图做形态学开运算效果立竿见影。4.2 遮挡边缘伪角点的处理用纯黑色填充遮挡区域理论上不会产生角点响应。但实际图像中标定板边缘并非锐利的矩形边界板子的外边框和背景之间可能存在复杂纹理。这些纹理在边缘处如果恰好形成黑白交替的图案就可能被OpenCV检测成伪角点。我的处理方式是在构建mask时并不使用完全刚性的矩形而是对mask做一次3x3的高斯模糊让遮挡区域和保留区域之间有一个柔和的过渡。当然这是因为我们标定的对象是内参对像素级边缘并不敏感轻微的软边不会影响计算结果。另一种做法是直接把整个保留区域之外的像素值设置为0但前提是标定板本身离画面边界足够远。如果标定板紧贴图像边缘遮挡区域的roi裁剪到图像边界后边缘处还是会出现一条亮边。这时候可以在cv2.copyMakeBorder的BORDER_CONSTANT模式下给图像外侧补一圈黑色边框再去做遮挡。4.3 标定结果焦距异常的处理如果标定跑完之后焦距为负或者重投影误差在几个像素以上最常见的原因是图像序列中出现了大量相似的图像。连续9张副本姿态完全一致如果后续bag中这些副本还排在一起Kalibr在优化外参时会倾向于把这些相似帧当作同一位置的重采样导致约束退化。解决方法在前面提过制作bag时把图像顺序打乱。我刚跑的时候是按照frame_0001_board_00到frame_0001_board_08的顺序写入bag的结果焦距偏了10%。后来改成随机洗牌同一组的9张图被分散到整个bag的各个位置焦距立即恢复正常。另一个隐藏原因是目标配置填错。检查target yaml里的targetCols和targetRows是不是内角点数sizeMeter的单位是不是米。这三个参数任何一个出错整个标定的标尺就错了焦距自然不对。我见过有人把内角点行列数和格子数目搞混的结果标出来的图像居然还能收敛但焦距单位差了一个格子。4.4 避坑检查清单下面这个表是我在实际标定过程中整理出来的检查点每次处理多板数据之前过一遍能省很多事。检查项具体要求可能后果相机曝光参数必须固定关闭自动曝光/自动增益遮挡后亮度变化导致角点丢失标定板规格所有板子同一型号内角点数和方格尺寸精确焦距单位错误、优化发散图像尺寸遮挡副本必须保持原始分辨率主点坐标和畸变模型错误遮挡边缘外扩10~15像素不要贴板裁切边缘伪角点导致检测错乱bag时间戳副本时间戳需合理分布图像顺序建议打乱相似帧连续导致约束退化数据量至少30组不同姿态的多板帧观测不足内参过拟合4.5 标定板标定和九点标定的区别顺便提一个容易被新手混淆的概念做内参标定的时候有些人会把“标定板标定”和“九点标定”混在一起其实这是两回事。标定板标定Kalibr、OpenCV棋盘格标定求解的是相机的内参和畸变属于相机自身属性的标定和机器人坐标系无关。九点标定是手眼标定或者相机到机器人坐标系的映射目的是求一个相机坐标到机器人坐标的变换关系通常要借助机械臂末端或者特定旋转机构在一个平面上取9个点来做刚体变换拟合。如果你做的项目是用单目相机识别目标位置并引导机械臂抓取那可能需要先后做标定板内参标定再做九点手眼标定两者缺一不可但千万别把它们当成同一个操作。内参标定错了九点标定再准也没用因为图像坐标系的畸变本身就带偏了。5. 边界情况与扩展5.1 多相机联合标定时也要这样吗如果你在一块布满9块板子的场景里同时用两个相机拍摄想用这批数据同时标定两个相机的内参和外参情况会稍微复杂一些。内参标定部分可以用我上面说的方法对每个相机的图像序列分别做“原图复制遮挡”各自标定出内参。这一步没有任何问题。但外参标定部分不能简单套用这个方案。外参标定的核心是求出两个相机坐标系之间的刚体变换这依赖于同一个标定板在同一个时刻被两个相机同时观测到。如果你把每个相机里的9块板子都拆成单板副本那么对于左右相机来说同一时刻对应的是不同位置的两块板子外参优化的约束矩阵就完全错乱了。所以多相机外参标定应该使用原始的多板图像让两个相机同时看到所有板子才能形成正确的极线约束。实践中我的建议是先分别用复制遮挡方法标好每个相机的内参然后把内参固定住再用同一批原始多板图像跑kalibr_calibrate_cameras的联合标定模式只优化外参。这一步Kalibr支持固定内参的配置具体在Kalibr官方文档里有说明。5.2 非棋盘格标定板也能用这个方案吗Kalibr不止支持棋盘格还支持AprilGrid、圆点阵等多种标定板类型。我的经验是对于AprilGrid这类带编码信息的标定板遮挡方案同样适用因为AprilGrid的检测器也会在图像中寻找唯一的tag网格。你把不相关的板子涂黑之后检测器只会看到目标区域行为就和单板场景一致。但对于圆点阵标定板需要额外注意一个问题圆点阵检测器对图像阈值和二值化质量比较敏感黑色填充背景可能会让ROI区域内的圆点对比度发生变化。我在测试中发现圆点阵用遮挡方案时需要把ROI外扩得更大一些避免黑色背景直接接触最外圈圆点。外扩20像素左右检测成功率明显提升。如果你的标定板混有不同尺寸或不同类型比如一张图里既有棋盘格又有AprilGrid那就不能用这个方案了。这种混合场景下Kalibr无法在一个target配置中描述两种标定板优化逻辑也完全错位建议重新采集数据保持所有板子类型一致。5.3 板子之间有重叠怎么办原图复制遮挡方案有一个明确的前置条件9块板子在图像中是完全独立的互不重叠也没有遮挡关系。如果标定板之间发生了部分重叠遮挡副本里保留的那块板子就会被另一块板子的边缘切掉一部分findChessboardCorners检测到的角点数量就会不够导致整个方案失效。这种场景只能重新采集数据。摆放板子的时候给每块板子之间留出至少5到10厘米的间距确保每块板子的外边框在图像中都是完整可见的。如果你的视场很小放不下9块独立板子那就减少数量用6块或者4块保证每块板子的完整性优先于数量。5.4 后续扩展方向这个方法本质上是一种“数据预处理思维”遇到工具处理不了的复杂输入不改工具先把数据拆分成工具擅长处理的子问题。这套思维不仅适用于Kalibr也适用于其他标定工具和视觉算法。比如你用OpenCV的calibrateCamera标定同样可以沿用遮挡逻辑比如你用YOLO训练目标检测遇到一张图里多个目标互相干扰也可以通过车道线遮挡或者区域mask来生成干净的正样本。行业里很多人一遇到问题就想着改源码、加参数、换工具其实很多时候改数据才是成本最低、最可控的解法。另外如果你经常处理这种多板数据还可以把这个脚本封装成一个带界面的小工具支持人工框选ROI、自动检测、bag生成一条龙。我在做这个方案的时候顺手写了一个命令行版本输入一个目录输出标定好的内参yaml几分钟完事。最后分享两个小技巧第一个是给图像副本加入轻微随机扰动。如果你的相机采集的每一帧多板图像姿态比较接近副本之间几乎没有差异可以在生成掩码副本时对保留区域的亮度做±2的随机扰动或者对ROI外扩范围加一点随机偏移。这样Kalibr在优化时会把每份副本当成稍微不同的观测避免了因为连续相似帧导致的数值退化。这个技巧在图像帧数少的时候尤其有效。第二个是标定完成之后一定要保留几张原始多板图像用于交叉验证。Kalibr给出的重投影误差只能反映拟合结果和检测点的吻合程度不能完全代表真实标定精度。我的验证方法是拿标定好的内参对原始多板图像重新跑一次角点投影查看9块板子的角点投影误差是否都小于0.5像素。如果某一块板的误差明显偏大说明这块板的遮挡副本可能有问题需要回去检查ROI是否准。多板标定的坑说到底就是一张图里信息太多超出了工具的处理范围。用“原图复制遮挡”把这堆信息拆开一张一张喂给Kalibr反而能把这9块板子的价值全部榨出来。希望这个方案也能帮到踩到同一个坑的人。
返回列表