相机标定实战:四种相机模型与四种标定板选型指南
发布时间:2026/9/30 10:03:42来源:尧图网络
简介这是一份面向计算机视觉与机器人视觉开发者的相机标定工具库同时支持单相机内参标定和双目相机相对位姿标定并可配合棋盘格、圆形网格、非对称圆形网格及ArUco等多种标定板使用。工具库覆盖针孔模型、Kannala-Brandt模型、MEI模型和Scaramuzza模型等常见相机模型能适应普通镜头与广角鱼眼镜头解决镜头畸变校正和三维重建中的参数估计问题。压缩包共包含225个文件大小约二十四兆其中十五个源代码文件和十七个头文件实现各模型核心算法及双目标定流程一百七十张图片提供标定样例另有参数配置、说明文档和脚本辅助使用。整体结构清晰代码便于直接运行和二次开发可快速集成到三维重建、自动驾驶、工业检测等系统目前已有一百零二人学习下载适合需要搭建标定模块的研究者和工程师。1. 相机内参标定和双目标定工具库为什么一个库要同时塞四种模型、四类标定板相机内参标定和双目标定是机器视觉里最容易被低估的一步。很多人对着 OpenCV 的calibrateCamera跑一遍看到重投影误差低于 0.1 就收工结果双目测距一上帧误差直接飙到厘米级。这个工具库把针孔模型、KannalaBrandt 模型、MEI 模型、Scaramuzza 模型四种相机模型和棋盘格、圆形网格、非对称圆形网格、ArUco 四类标定板收进同一套流程不是为了炫技而是因为常规工业镜头只是起点鱼眼镜头、折反射全向相机、大倾角标定板才是真正难啃的硬骨头。适合做单目测距、双目深度、机械臂抓取定位又不愿意在标定环节反复返工的人。2. 四种相机模型怎么选针孔、KannalaBrandt、MEI、Scaramuzza 的适用边界与畸变参数差异先看模型再谈流程。工具库真正值钱的地方是它没把鱼眼、全向相机当做“畸变特别大的针孔”来处理而是给了四种独立的投影模型。选错模型的后果不是精度差一星半点而是求解器根本不收敛或者每次标定出来的内参矩阵都不一样。理解这四种模型只需要抓住一件事它们各自假设了什么样的投影关系以及畸变参数打算拟合到哪一阶。2.1 针孔模型标定结果最稳但只对窄视场镜头成立针孔模型是 OpenCV 默认的相机模型也是大多数人最早接触的标定入口。它的投影关系是x K [R|t] X畸变模型只处理两种偏离径向畸变镜头曲率引起的桶形/枕形畸变和切向畸变透镜与传感器不完全平行引起的偏心畸变。OpenCV 里最常用的畸变向量是(k1, k2, p1, p2[, k3])其中 k 是径向畸变系数p 是切向畸变系数。这套模型在视场角 60 度以内的工业镜头上非常稳误差收敛快结果可复现。但如果镜头视场角到了 90 度以上边缘像素的投影关系已经严重偏离针孔假设五个畸变系数根本不够用。OpenCV 提供了CALIB_RATIONAL_MODEL标志把畸变向量扩充到八个数(k1, k2, p1, p2, k3, k4, k5, k6)能勉强拟合一些广角镜头但这不是鱼眼的正解。我的经验是一旦发现标定结果需要依赖k3才过得去而且fx、fy在不同图片子集下标出来差别超过两个像素就该考虑换模型了。这里要特别注意畸变系数的顺序。针孔模型的畸变向量顺序是k1, k2, p1, p2, k3而鱼眼模型的顺序是k1, k2, k3, k4两者不能混用。工具库如果支持多种模型内部一定会在读入标定参数时做一次模型标记否则把鱼眼的四元素畸变向量喂给针孔模型去去畸变出来的图会花掉。2.2 KannalaBrandt 模型鱼眼镜头标定的正解KannalaBrandt 模型是鱼眼镜头的等距投影模型OpenCV 的fisheye模块直接实现了它。它的核心假设是入射角为 theta 的光线在传感器上的成像半径 r 与 theta 近似成正比畸变多项式写为r_d theta * (1 k1 * theta^2 k2 * theta^4 k3 * theta^6 k4 * theta^8)四个畸变系数 k1 到 k4配合内参矩阵 K就能描述视场角接近甚至超过 180 度的鱼眼镜头。用针孔模型去拟合同一支鱼眼镜头径向畸变系数会互相较劲牛顿迭代经常掉进局部极小值换到 KannalaBrandt 模型之后同样的图片集通常一次就收敛。用 OpenCV 的fisheye::calibrate时有个和针孔模型差异很大的地方它不能像calibrateCamera那样直接传None让函数内部初始化内参必须显式给一个初始 K 矩阵和畸变向量 D。初始 K 的主点可以直接用图像中心(w/2, h/2)fx、fy给一个按镜头标称焦距换算的初值。另外建议固定CALIB_FIX_SKEW因为绝大多数鱼眼传感器的像素是正方形放开 skew 自由度只会让求解器多一个不稳定的变量。2.3 MEI 和 Scaramuzza 模型全向相机怎么建模MEI 模型是针对折反射相机提出的。折反射相机用双曲面镜或抛物面镜反射光线再用普通镜头拍照成像关系里多了一个镜面几何参数 xi。MEI 模型的思路是先把空间点按镜面反射关系映射到一个虚拟针孔平面再做一次针孔投影。OpenCV 的omnidir模块里CALIB_MEI标志对应的就是这套模型它会多估计一个镜面参数 xi外加四个畸变系数。Scaramuzza 模型走的是另一条路不管镜面是什么形状直接用一个泰勒多项式拟合从入射角到成像半径的映射关系。OpenCVomnidir模块的CALIB_OMNIDIR标志对应的就是这套模型。它的好处是方便拿到一个不知道镜面参数手册的全向镜头也能硬标出来坏处是物理意义不如 MEI 直观投影关系是个黑匣子后续要在算法里显式调用投影函数时不如 MEI 好理解。工具库里同时支持这两者我的理解是它没有在这两个模型之间二选一而是留了两个入口确认镜面几何参数、想控制每个中间变量的选 MEI手里只有镜头、没有参数手册的选 Scaramuzza。实际项目中全向相机在室内 SLAM 和巡检机器人里用得比较多标定时注意采集范围要覆盖镜面边缘区域那里畸变变化最剧烈数据少了下不去。2.4 四种模型速查表模型OpenCV 入口畸变参数形态适用镜头针孔cv2.calibrateCamerak1, k2, p1, p2, k3常规工业镜头视场角 90 度KannalaBrandtcv2.fisheye.calibratek1, k2, k3, k4鱼眼镜头视场角 90 度MEIcv2.omnidir.calibrateCALIB_MEIxi 4 个畸变系数折反射全向相机Scaramuzzacv2.omnidir.calibrateCALIB_OMNIDIR泰勒多项式系数鱼眼、全向相机无镜面参数手册选模型和选标定板是两件独立的事。KannalaBrandt 模型配棋盘格是常规组合但配 ArUco 板在鱼眼边缘视角下检测更稳定全向相机配棋盘格则经常因为边缘角点拉得太开导致检测失败换非对称圆形网格或 ArUco 会好很多。这也是工具库要同时支持多种标定板的原因——标定板不是打印一张纸的事它是模型求解能否拿到足够多有效观测的前提。3. 标定板不是随便打印一张纸棋盘格、圆形网格、非对称圆形网格、ArUco 的选型与生成标定板提供的是空间中的已知点标定过程靠这些点的像素位置反推相机参数。所以标定板的核心指标不是好看而是特征点能不能被稳定、精确地提取出来以及提取到的点在物理世界里到底对应多大间距。这个间距错了内参矩阵里的焦距尺度就全错了。3.1 棋盘格最通用但遮挡和倾角是它的软肋棋盘格是入门首选用cv2.findChessboardCorners找角点再做亚像素细化。它的优点是角点提取精度高对视角变化的响应比较线性缺点是要求整个棋盘格完整出现在画面里只要有一块被遮挡整帧直接判定失败。大倾角下格子被压得很扁亚像素窗口里的梯度方向变得不明显角点提取精度也会下降。打印棋盘格时有几件事不能省方格边长要量准角点数量要按内角点算比如 9x6 指的是内部角点 9 列 6 行板子要贴在平整的铝板或玻璃板上不能是软纸板。软纸板在斜拍时会产生明显的弯曲标定出来的畸变参数会把板子本身的弯曲当镜头畸变拟合进去这是最常见的隐性误差来源。亚像素细化的参数也需要看情况调。比较稳的窗口是(11, 11)终止条件给(EPS MAX_ITER, 30, 0.001)。如果标定板在画面里占比很小角点像素细节少可以适当放大窗口但注意窗口太大容易把相邻角点的梯度混进来。3.2 圆形网格 vs 非对称圆形网格圆心检测更抗模糊但方向歧义要命圆形网格的特征点是圆心用cv2.findCirclesGrid配合 blob 检测提取。圆心的优势是检测对图像模糊不敏感适合运动模糊明显的场景劣势是在大倾角下圆在图像里变成椭圆椭圆拟合出的中心与真实圆心之间会有系统性偏移。这个偏移打着“亚像素精度”的旗号混进标定结果很难察觉。对称圆形网格还有个隐藏问题当标定板旋转 180 度时提取到的圆心阵列在物理坐标上无法区分左右方向OpenCV 的排序逻辑可能给出两种完全不同的物点对应关系。非对称圆形网格就是为这个场景设计的——每一行的圆数量交替变化比如奇数行 4 个、偶数行 5 个这样旋转 180 度后模式不再对称物点顺序唯一确定。这也是工具库单独把非对称圆形网格列为一大类的原因。使用圆形网格时blob 检测器的参数要单独调。默认的SimpleBlobDetector会把高光噪点、反光斑也当成候选圆出现检测的圆数量大于实际数量。一般会限制minCircularity到 0.8 左右minDistBetweenBlobs给圆心间距的一半滤掉杂点。3.3 ArUco 板鱼眼和全向相机的救星ArUco 是编码标记板每个 marker 自带唯一的 ID哪怕部分遮挡也能靠剩余模块解码定位。这解决了棋盘格“整板可见”的硬性要求。更实用的是 Charuco 板在棋盘格的格子里嵌入 ArUco marker检测时先用 ArUco 做粗定位再取棋盘格角点做亚像素细化兼顾了鲁棒性和精度。鱼眼镜头标定是我用 ArUco 最多的场景。鱼眼画面边缘畸变极大棋盘格在边缘经常提取失败而 Charuco 板因为每个 marker 独立解码边缘处的 marker 可以逐个识别配合 KannalaBrandt 模型标定一次通过的几率比棋盘格高很多。ArUco 唯一的坑是尺寸markerLength必须量实物黑色边框的外沿边长单位统一用毫米填错了外参的尺度全错内参里fx却不受影响——所以很多人标完看内参觉得没问题一放到机器人的手眼标定里就发现平移量离谱。3.4 用 OpenCV 生成四类标定板最小脚本与参数说明常见做法是自己写脚本生成标定板图片再按 1:1 打印。下面给一个生成棋盘格、非对称圆形网格和 ArUco 标记的最小脚本。import cv2 import numpy as np import cv2.aruco as aruco # ---------- 棋盘格9x6 内角点每格 100px ---------- inner_w, inner_h 9, 6 cell 100 img np.full(((inner_h 1) * cell, (inner_w 1) * cell), 255, dtypenp.uint8) for i in range(inner_h 1): for j in range(inner_w 1): if (i j) % 2 0: img[i*cell:(i1)*cell, j*cell:(j1)*cell] 0 cv2.imwrite(chessboard_9x6.png, img) # ---------- 非对称圆形网格4 行圆数 4、5 交替间距 120px ---------- rows 4 spacing 120 radius 25 col_a, col_b 4, 5 img np.full((rows * spacing, col_b * spacing), 255, dtypenp.uint8) for r in range(rows): n col_a if r % 2 0 else col_b x0 (col_b * spacing - (n - 1) * spacing) // 2 y r * spacing spacing // 2 for c in range(n): cv2.circle(img, (x0 c * spacing, y), radius, 0, -1) cv2.imwrite(asymcircles_4x5.png, img) # ---------- ArUcoDICT_6X6_50 的 id0 和 id1各 200x200px ---------- dictionary aruco.getPredefinedDictionary(aruco.DICT_6X6_50) for marker_id in (0, 1): marker aruco.generateImageMarker(dictionary, marker_id, 200) cv2.imwrite(faruco_id{marker_id}.png, marker)代码里的inner_w, inner_h指定的是内部角点数打印时外围还要留至少一个格子的空白边避免检测时把边界格子裁掉。非对称圆形网格的spacing是圆心间距像素值radius是圆的半径像素值打印时这两个值决定板子的物理尺寸检测端传入的patternSize在非对称网格下要填每一行最大的圆数量和行数比如这里填(5, 4)。ArUco 的DICT_6X6_50表示 6x6 位编码、最多 50 个标记标定一般用DICT_6X6_250或者DICT_5X5_100都行关键是要在检测端使用同一个字典否则解码全部失败。4. 把工具库跑起来从图像采集到双目标定的完整流程与关键参数这个工具库的常见形态是三段式先做特征检测再做单目标定或双目标定最后输出标定报告和校正映射表。部署方式一般是一条命令行入口加一个配置文件配置文件里写明用哪个相机模型、哪类标定板、图像路径和输出目录。下面不针对某个具体命令而是把工具库内部必然要走的完整流程拆开讲这样换到任何封装都能对上号。4.1 采集决定成败的 80%标定结果的上限在采集阶段就定死了。图片数量太少误差数字会虚低换一组图内参就飘角度分布太集中畸变参数只在中间视场被约束边缘视场的畸变全靠外推。我的习惯是采 20 到 25 张有效图覆盖画面中心、四个角落、上下左右倾角各几张标定板要占到画面面积的 1/4 到 1/3。光照也影响巨大。标定板表面要均匀受光避免高光和反光否则棋盘格角点的亚像素窗口里会出现虚假梯度ArUco 的解码也会闪断。拍摄时相机固定板子动不要一边移动相机一边移动板子否则运动模糊会污染角点位置。采完图先人工扫一遍删掉模糊帧再进标定流程。4.2 单目内参标定针孔模型和鱼眼模型的最小可跑代码先看最常用的针孔模型单目标定。import cv2, glob, numpy as np pattern (9, 6) square_mm 20.0 # 每个方格的物理边长单位 mm # 物点以棋盘格平面为 z0单位取方格边长 objp np.zeros((np.prod(pattern), 3), np.float32) objp[:, :2] np.mgrid[0:pattern[0], 0:pattern[1]].T.reshape(-1, 2) objp * square_mm # tvec 的单位随之变为 mm obj_points, img_points [], [] for f in sorted(glob.glob(imgs/*.jpg)): img cv2.imread(f) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, corners cv2.findChessboardCorners(gray, pattern, None) if not ret: print(跳过失败帧:, f) continue crit (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), crit) obj_points.append(objp) img_points.append(corners) ret, K, dist, rvecs, tvecs cv2.calibrateCamera( obj_points, img_points, gray.shape[::-1], None, None ) print(RMS:, ret) print(内参矩阵:\n, K) print(畸变系数:, dist.ravel())这段代码里objp * square_mm很关键如果物点单位是方格边长倍数也能标出正确的 K但tvecs的单位没有物理意义乘以实际边长之后外参平移量直接是毫米单位后面做手眼标定或者单目测距可以直接用。RMS 只是重投影误差的平均值不能只看这一个数要把每帧的残差分布打印出来检查有没有某一帧特别大。鱼眼模型的标定代码差别比较明显。import cv2, glob, numpy as np pattern (9, 6) objp np.zeros((1, np.prod(pattern), 3), np.float32) objp[0, :, :2] np.mgrid[0:pattern[0], 0:pattern[1]].T.reshape(-1, 2) obj_points, img_points [], [] for f in sorted(glob.glob(fisheye/*.jpg)): img cv2.imread(f) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, corners cv2.findChessboardCorners(gray, pattern, None) if ret: crit (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), crit) obj_points.append(objp) img_points.append(corners.reshape(1, -1, 2)) h, w gray.shape K np.array([[w, 0, w/2], [0, w, h/2], [0, 0, 1]], dtypenp.float64) D np.zeros((4, 1), dtypenp.float64) rvecs [np.zeros((1, 1, 3), np.float64) for _ in obj_points] tvecs [np.zeros((1, 1, 3), np.float64) for _ in obj_points] rms, K, D, rvecs, tvecs cv2.fisheye.calibrate( obj_points, img_points, (w, h), K, D, rvecs, tvecs, cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC cv2.fisheye.CALIB_FIX_SKEW ) print(RMS:, rms) print(K:\n, K) print(D:, D.ravel())鱼眼模型的物点形状要求是1xNx3这和针孔模型的Nx3不同是最容易踩的坑。CALIB_RECOMPUTE_EXTRINSIC让每次迭代重新计算外参加速收敛CALIB_FIX_SKEW固定传感器像素为正方形。如果标出来的主点cx, cy偏离图像中心太多通常不是镜头问题而是图片里标定板始终偏向一侧采集时要注意让标定板出现在画面各个位置。4.3 双目标定立体标定、极线校正与校正映射双目相机标定是在两个单目内参的基础上求解两相机之间的旋转矩阵 R 和平移向量 T。常见做法是先用 4.2 的方法分别标出左右目的 K1、D1、K2、D2再做立体标定。import cv2, glob, numpy as np # obj_points_l / obj_points_r左右目各自的物点列表 # img_points_l / img_points_r左右目各自的像点列表结构同单目 # K1, D1, K2, D2左右目已标定的内参与畸变系数 # gray.shape[::-1]图像尺寸 (w, h) crit (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6) rms, K1, D1, K2, D2, R, T, E, F cv2.stereoCalibrate( obj_points_l, img_points_l, img_points_r, K1, D1, K2, D2, gray.shape[::-1], criteriacrit, flagscv2.CALIB_FIX_INTRINSIC ) R1, R2, P1, P2, Q, _, _ cv2.stereoRectify( K1, D1, K2, D2, gray.shape[::-1], R, T, alpha0.0 ) map1l, map2l cv2.initUndistortRectifyMap(K1, D1, R1, P1, gray.shape[::-1], cv2.CV_32FC1) map1r, map2r cv2.initUndistortRectifyMap(K2, D2, R2, P2, gray.shape[::-1], cv2.CV_32FC1) rect_l cv2.remap(img_l, map1l, map2l, cv2.INTER_LINEAR) rect_r cv2.remap(img_r, map1r, map2r, cv2.INTER_LINEAR)CALIB_FIX_INTRINSIC的意思是立体标定只优化 R、T左右目内参保持单目标定结果不变这是最稳妥的做法。如果单目标定质量一般可以换成CALIB_USE_INTRINSIC_GUESS让立体标定对内参做微调但前提是两目图片数量足够多。alpha0.0会让校正后的图像裁剪掉黑边缺点是损失部分视野alpha1.0保留全部视野但黑边明显实际项目里我默认用 0。Q矩阵把视差转成深度z Q[3,2] / (x_l - x_r)其中x_l - x_r是视差值。拿到Q之后测距不需要再展开任何外参计算直接算视差就行。4.4 结果怎么用内参矩阵、畸变系数、外参的物理含义标定输出里最常用的是四样东西。内参矩阵 K 里的fx, fy是焦距的像素单位它们等于物理焦距除以单像素尺寸cx, cy是主点理论上接近图像中心偏移量反映了镜头光轴与传感器中心的偏差。畸变系数 D 是去畸变和校正的直接输入注意不同模型的顺序和含义。R、T 是双目外参描述右相机相对左相机的姿态。E 和 F 分别是本质矩阵和基础矩阵在双目视觉里主要用于极线约束实际工程中用的不多。提示保存标定结果时建议把模型类型、标定板类型、图像尺寸一起写进配置不要只存 K 和 D。后续做去畸变、极线校正时同一个参数文件在不同 OpenCV 接口里的解释不一样模型信息能帮你少走弯路。5. 避坑与排查标定结果不稳定的五个翻车现场标定这种事误差数字全会骗人现场验证才会说实话。下面这五个坑是我自己踩过、也在别人的项目里见过无数次的按“现象、原因、解决”直接给结论。5.1 重投影误差 0.1 以内但双目测距偏了 3 厘米现象内参标定和立体标定的 RMS 都很好看0.05 到 0.1 之间一放到实际测距场景3 米处误差 3 厘米且误差随距离线性增大。原因重投影误差描述的是“标定板上的点投回图像的误差”如果标定板本身不平或者图片只有十几张且角度单一误差会虚低内参里的焦距和畸变并没有被充分约束。解决标定板贴铝板或玻璃板重新采集 20 张以上覆盖四角和倾角再标一次。RMS 变大了不要慌那才是真实水平。5.2 同一支鱼眼镜头两次标定的内参差很多现象同一批图两次运行标定fx差了十几个像素主点偏移明显。原因大概率用了针孔模型去标鱼眼镜头畸变参数互相补偿把镜头模型硬塞进一个不匹配的假设里也可能是fisheye::calibrate的初始 K 给得太随意。解决换 KannalaBrandt 模型初始 K 用图像中心作主点fx按镜头标称焦距估一个初值固定 skew再对比多次结果fx波动应该在 2 像素以内。5.3 圆形网格检测出多余圆或者漏检现象findCirclesGrid报错说找不到完整网格二值化后肉眼看到十几个圆点但程序只检测到七八个。原因SimpleBlobDetector默认参数把反光高光点当成候选圆或者目标圆和背景对比度太低blob 的面积和圆度过滤条件不合适。解决显式创建 blob detector把minDistBetweenBlobs设为圆心间距的一半minCircularity提到 0.8minArea按图像里圆的实际像素面积设到三分之一左右。5.4 极线校正后图像黑边很大或者校正后主点偏移现象stereoRectify之后左右图黑边一大片或者目标只在特定距离才有正确视差。原因alpha参数设置问题。alpha0会裁剪到无黑边但有图像缩放alpha1保留全视野但黑边明显还有一种情况是两目采集的图像没有同步左右图里运动物体位置不一致导致校正后边缘畸变。解决先用alpha0.0跑通流程确认极线水平了再考虑视野同步问题需要在采集端做硬触发软件时间戳只能缓解。5.5 ArUco 标定出来的外参尺度不对现象单目内参看起来正常但把标定板放在已知距离处验证位姿平移量的单位对不上。原因markerLength填错了。有人填的是 marker 图像分辨率对应的像素值有人量的是 marker 白色内边而不是黑色外沿还有人毫米和英寸混用。解决统一用毫米量黑色边框外沿的实际边长复核 Charuco 板时squareLength和markerLength填对应的两个尺寸不能都填同一个数。6. 标定结果准不准三个不依赖误差数值的验证技巧标定报告的 RMS 只是一个必要条件真正可靠的验证是拿标定结果回到图像上做闭环检查。这里给三个我每次标定完都会做的验证动作。第一反投影残差分布。把某一帧的物点用标定出的内外参重新投影回图像逐点算像素残差。代码很简单proj, _ cv2.projectPoints(objp, rvecs[i], tvecs[i], K, dist) res np.linalg.norm(proj.reshape(-1, 2) - img_points[i].reshape(-1, 2), axis1) print(该帧最大残差:, res.max(), 平均残差:, res.mean())如果某一两个角点残差明显大于平均值多半是那帧的标定板局部反光或者亚像素细化跑了偏删掉重标。第二极线约束检查。双目校正后在左图里取某个角点把它的齐次坐标乘基础矩阵 F在右图画出对应极线看极线是否穿过右图同名点。允许的误差通常在一个像素级别如果极线偏差超过两个像素说明双目标定结果有问题需要回头检查左右目单目标定的一致性。第三稳定性检验。把采集的图片随机抽两次 15 张的独立子集分别标定比较两次fx和主点cx, cy。fx波动应该在 0.5% 以内主点波动在 2 像素以内才算稳定。最后用一个已知距离验证深度比如把标定板放在距相机 50 厘米的位置用Q矩阵算出的深度与实测值对比3 米内误差小于 2% 才能进场使用。我个人的习惯是标定完成不急着删采集的原始图留着原始图就是后悔药。因为工具库支持多种模型和标定板同一组数据换一个模型重新标一遍的成本很低但重新采集一次的成本很高。尤其是鱼眼和全向相机现场架子拆了再装就回不去了。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网