news 2026/10/16 7:04:17

SensorsCalibration 环绕相机标定指南:四套 AVM 工具(无标定板/标定板/手动/鱼眼)的原理与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SensorsCalibration 环绕相机标定指南:四套 AVM 工具(无标定板/标定板/手动/鱼眼)的原理与实战
  • 自动驾驶
  • 计算机视觉

【免费下载链接】SensorsCalibration

OpenCalib: A Multi-sensor Calibration Toolbox for Autonomous Driving

项目地址:https://gitcode.com/gh_mirrors/se/SensorsCalibration
点击查看免费下载

导读

本文围绕开源多传感器标定工具箱 SensorsCalibration 中的 surround-camera 模块,系统讲解自动驾驶环视(Surround View / AVM)相机外参标定的四套工具:面向普通环视相机的 target-less 自动标定(auto_calib)、面向环视鱼眼相机的 target-less 自动标定(auto_calib_fisheye)、基于标定板的产线级自动标定(auto_calib_target),以及支持 pinhole / Ocam / fisheye 三种模型的交互式手动标定(manual_calib)。读完本文,你将掌握每套工具的适用场景、编译运行方式、命令行参数、相机模型选择依据,以及从 BEV 投影、纹理提取到随机搜索优化(coarse-to-fine)的完整算法链路,并能在真实部署中根据传感器类型(普通相机或鱼眼)与场景(道路 or 产线)正确选择工具。

一、模块总览:一套 AVM 工具箱,四种标定路线

surround-camera/README.md 将本模块定位为 "a calibration toolbox for surround view cameras or surround view fisheye cameras",即同时覆盖普通环视相机与环视鱼眼相机。四套工具的选型关系可用下表概括(来源于该 README 的工具矩阵):

calibration paramcalibration typecalibration methodmannual calibrationauto calibrationusage documentation
surround_cameras (fisheye)extrinsictarget-less✔manual_calib
surround_cameras (fisheye)extrinsictarget-less✔auto_calib_fisheye
surround_camerasextrinsictarget-less✔auto_calib
surround_camerasextrinsictarget✔auto_calib_target

几点关键结论:

  • 四套工具全部解决**外参(extrinsic)**标定问题,即各环视相机相对车体(或 BEV 地面坐标系)的旋转和平移。
  • 前三套标定路线均为target-less(无标定板),依靠场景自然纹理完成自动优化;只有 auto_calib_target 属于target(标定板)路线,且 README 明确指出它可用于环视相机生产线的标定("This tool can be used for production line calibration of surround view cameras")。
  • 手动标定(manual_calib)同时支持普通环视相机与鱼眼环视相机,是唯一同时覆盖两种传感器的手动方案。

从仓库目录结构看,四个子模块的实现高度同构:auto_calib 与 auto_calib_fisheye 均包含include/{optimizer.h, texture_extractor.h, transform_util.h}与src/{calibration.cpp, optimizer.cpp, texture_extractor.cpp},二者的核心区别在于主程序入口(main)中选择的camera_model与data_set;manual_calib 依赖 include/extrinsic_param.hpp 与 include/intrinsic_param.hpp 从 JSON 加载内参/外参;auto_calib_target 则包含独立的 src/calibration.cpp(solvePnP 求解外参)与 src/stitching.cpp(环视拼接验证)。

二、编译与运行:统一构建流程与可执行文件约定

四套工具都采用标准 CMake 构建流程,各子模块 README 中给出的编译步骤完全一致:

mkdir -p build && cd build cmake .. && make

构建产物统一输出到模块根目录下的bin/目录(由各 CMakeLists.txt 的set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)决定,见 auto_calib/CMakeLists.txt)。

各工具的可执行文件与运行方式如下:

工具可执行文件运行方式(在模块根目录执行)
auto_calibrun_AVM_Calibrationcd ~./auto_calib/后./bin/run_AVM_Calibration
auto_calib_fisheyerun_AVM_Calibrationcd ~./auto_calib_fisheye/后./bin/run_AVM_Calibration
auto_calib_targetrun_AVM_Calibration/run_stitching./bin/run_AVM_Calibration或./bin/run_stitching
manual_calibrun_avm见下节命令行参数

其中 auto_calib 与 auto_calib_fisheye 的 CMakeLists 均为project(online_Calibration)、add_executable(run_AVM_Calibration src/calibration.cpp)(fisheye 版 与 普通版 完全一致),因此可执行文件名相同,需要放在各自目录下运行。

2.1 依赖与构建前提

从 CMakeLists 可归纳出构建依赖:

  • auto_calib / auto_calib_fisheye:C++17(-std=c++17 -pthread,用于多线程随机搜索)、Eigen3(/usr/include/eigen3)、OpenCV(find_package(OpenCV REQUIRED),代码中用到fisheye::distortPoints、remap、findContours等接口)。
  • auto_calib_target:C++11、Eigen3、OpenCV;CMake 默认在/usr/local/opencv-2.4.13/share/OpenCV/下查找 OpenCV 2.4.13(NO_DEFAULT_PATH),若使用其他版本需自行调整该路径。
  • manual_calib:C++11、Pangolin(GUI 显示)、Boost(filesystem、system)、OpenCV、jsoncpp(libjsoncpp.a),链接关系见 manual_calib/CMakeLists.txt。

2.2 运行示例与输出

无标定板自动标定(auto_calib / auto_calib_fisheye)为无参数交互程序:入口 main 直接读取./imgs/下的Front/Left/Back/Right四张图像(普通版为 png、鱼眼版为 jpg),标定过程中会依次打印左/右/后相机各阶段(1st 粗搜、2nd 精调、3rd 微调)的 luminosity loss、最优搜索参数(roll/pitch/yaw/tx/ty/tz)与优化后的外参矩阵,最终在模块根目录输出拼接结果图after_all_calib.png,并将各阶段对比图写入after_*_calib*.png(详见 auto_calib/src/calibration.cpp)。

auto_calib_target 的run_stitching直接读取imgs/front_125.png等四张图像,投影到地面后用addWeighted叠加生成并保存surround_view.png(stitching.cpp)。

三、无标定板自动标定:auto_calib 与 auto_calib_fisheye

这两套工具共享同一套算法框架(optimizer + texture_extractor),仅通过 main 中的三个配置项区分:

// camera_model: 0-fisheye; 1-Ocam; 2-pinhole int camera_model = 2; // auto_calib 用 pinhole int camera_model = 0; // auto_calib_fisheye 用 fisheye string data_set = "common"; // auto_calib string data_set = "fisheye"; // auto_calib_fisheye

camera_model控制投影时使用的畸变模型(见Optimizer::project_on_ground中fisheye::distortPoints/distortPointsOcam/distortPoints三分支),data_set则决定内参、畸变、外参初值、BEV 高度与裁剪尺寸等初始化参数(见 optimizer.cpp 的initializeK/initializeD/initializePose/initializeKG/initializeHeight/initializetailsize)。

3.1 算法主链路:BEV 投影 → 公共视野纹理提取 → 光度一致性优化

整个标定流程(以fixed = "front"固定前相机为例)可分为四步:

  1. 生成初始 BEV 鸟瞰图:利用四台相机初始外参T_CG(ground→camera)、内参K_C、畸变D_C与地面相机内参K_G,对地面网格像素逐个反投影、畸变、remap采样,得到四张 BEV 图(project_on_ground,代码见 optimizer.cpp)。
  2. 裁剪公共视野区域:Optimizer::tail按sizef/sizel/sizeb/sizer保留前/左/后/右相机各自靠近车身一侧的条带区域,其余区域补黑(optimizer.cpp),使相邻相机之间形成可比较的公共视野。
  3. 纹理提取:extractor对相邻 BEV 对(fl/fr/bl/br)做二值化(Binarization,两图同位置均非黑则置 255)、膨胀腐蚀与findContours提取最大轮廓,再按梯度幅值筛选纹理点并随机下采样 500 个点,同时计算曝光补偿系数ncoef(两图公共视野平均灰度的比值)与各相机灰度gamma校正(见 texture_extractor.cpp)。
  4. 光度一致性随机搜索优化:以待标定相机外参微扰deltaT将 BEV 纹理点重投影到相邻相机图像上,计算灰度差平方和作为 loss,用多线程随机采样最小化。

标定顺序上,前相机固定,先标 right,再标 left,最后标 behind(main 中的调用顺序),每次标定完会用最优外参重新生成该相机 BEV 并更新公共视野纹理。

3.2 粗到精(coarse-to-fine)三阶段搜索策略

CameraOptimization(见 auto_calib/src/calibration.cpp)对每个相机依次执行三阶段搜索,各阶段参数如下:

阶段线程数迭代次数roll/pitch/yaw 搜索范围tx/ty/tz 搜索范围
1st 粗搜(coarse)7100000/线程[-3°, 3°] 按 x/y/z 轴拆分区间[-0.01, 0.01] m
2nd 精调(fine)615000/线程[-1°, 1°] 为主[-0.005, 0.005] m 为主
3rd 微调(fine)38000/线程[-0.01°, 0.01°][-0.002, 0.002] m

第一阶段的 7 个线程将三维姿态空间(每个轴 [-3,3] 度)拆分成若干子区间并行搜索(例如Calibrate_right(iter_nums, -3, 3, -3, 3, -3, 3, ...)),随后用fine_random_search_params在更小邻域继续细化。搜索过程中使用独立 mutex 保护各相机的最优解更新(mutexleft/mutexright/mutexbehind),并且只有 loss 严格下降才接受新外参(random_search_params与fine_random_search_params中的loss_new < cur_*_loss判断,见 optimizer.cpp)。

对畸变模型的适配细节:优化过程中back_camera_and_compute_loss重投影纹理点时同样按camera_model选择fisheye::distortPoints、distortPointsOcam或简化 pinhole 投影(optimizer.cpp)。

3.3 两种数据集的关键初始化参数对比

data_set为 "common"(auto_calib)与 "fisheye"(auto_calib_fisheye)时,初始化参数差异如下(均取自initialize*系列函数):

参数common(pinhole)fisheye
相机内参 K(示例 Front)fx=fy=390.425287, cx=cy=750fx≈422.13, cx≈612.83, cy≈545.06(四相机各异)
畸变 D(示例 Front)[0,0,0,0][-0.07031853, 0.00387505, -0.00333139, 0.00056406]
地面 BEV 内参 K_Gfx=fy=390.425287, cx=cy=750fx=1/0.15, fy=-1/0.15, cx=bcols/2, cy=brows/2
相机高度 h5.1 m(四相机)1.0 m(四相机)
tail 裁剪尺寸sizef=sizel=sizer=450, sizeb=350sizef=340, sizel=sizer=390, sizeb=380
BEV 尺寸1500×15001000×1000

需要说明的是,common 数据集的初始外参T_CG中还叠加了人为施加的姿态扰动(left/right/behind 的扰动欧拉角与平移见 optimizer.cpp),用于模拟真实安装误差并验证优化算法的收敛能力;fisheye 数据集则直接使用 ROCES 标定结果作为初值。

3.4 曝光一致性处理

由于四台相机曝光参数未必一致,公共视野两侧灰度可能存在系统性偏差。纹理提取阶段通过exposure_flag开关控制:开启时ncoef = mean(gray1) / mean(gray2)(公共视野平均灰度比),优化 loss 计算中将参照侧灰度除以该系数后再做差,从而把曝光差异从几何误差中解耦。auto_calib 中 fl/fr 对exposure_flag=0、bl/br 对exposure_flag=0,而 auto_calib_fisheye 全部置 1,且对 bl/br 还启用了公共视野边缘过滤(edge_flag=1,按与相机中心的距离剔除贴近 BEV 边缘的弱纹理点)。这些开关均为 main 中的可调参数(auto_calib_fisheye/src/calibration.cpp)。

3.5 结果可视化对比

auto_calib 与 auto_calib_fisheye 在优化前会先用初始外参生成before_all_calib.png,优化结束后用SaveOptResult基于最终外参生成after_all_calib.png。两个版本仓库内均附带示例结果图:

  • 普通环视相机版本:标定前 before_all_calib.png 与标定后 after_all_calib.png;
  • 鱼眼环视版本:标定前 before_all_calib.png 与标定后 after_all_calib.png。

注意:标定板在无标定板自动标定中仅起到提供纹理信息的作用(README 原文 "the calibration board here only provides some texture information"),并不参与几何约束求解。

四、基于标定板的产线级自动标定:auto_calib_target

auto_calib_target 面向生产场景,思路与无标定板路线完全不同:它利用已知车体系 3D 点与图像 2D 点的一一对应,通过solvePnP直接求解各相机外参。

4.1 求解流程:已知 3D 点 + 2D 点 → solvePnP

src/calibration.cpp 的 main 中:

  1. InitializeK为四台相机设置相同的针孔内参(fx=fy=390.425287, cx=cy=750),InitializeD将畸变置零(5 维向量全 0)。
  2. Initialize3dPoints定义标定板特征点在车体坐标系下的 3D 坐标,例如前相机前方x=3.5 m平面上的 12 个点((3.5, ±0.12, ±0.36)等),左/后/右相机分别对应y=2.0 / x=-3.0 / y=-2.0平面上的对称点组(见 calibration.cpp)。
  3. Initialize2dPoints给出同一组特征点在四张图像中的像素坐标(2D 匹配点,calibration.cpp)。
  4. 对每台相机依次调用solvePnP(pts_3d, pts_2d, K, D, rvecs, translation)求解旋转向量与平移,再经Rodrigues转为旋转矩阵,hconcat拼成 4×4 外参矩阵T_F/T_L/T_B/T_R并打印(calibration.cpp)。

因此,要移植到自己的产线,核心工作量在于替换上述 3D 点(由标定板相对车体的精确安装位置决定)与 2D 点(标定板角点/特征在图像中的检测结果,当前仓库为手工预设样本)。

4.2 拼接验证工具 run_stitching

src/stitching.cpp 提供独立的环视拼接验证程序:读取imgs/front_125.png等四张图,用初始化函数中的内参/外参投影到 1500×1500 的 BEV(dX=dY=0.005,即 5 mm/像素),将各相机 BEV 裁剪掉互相遮挡的区域后以 0.5 权重addWeighted叠加生成surround_view.png(stitching.cpp)。该工具可快速检验 auto_calib_target 求出的外参是否能让环视画面无缝拼接。

仓库内附带四张带标定板图像的 BEV 投影验证结果:前 img_GF.png、左 img_GL.png、后 img_GB.png、右 img_GR.png,以及最终 surround_view.png。

五、交互式手动标定:manual_calib

manual_calib 提供基于 Pangolin 的实时可视化手动微调工具,支持 pinhole、Ocam(全方位相机)、fisheye 三种相机模型,仓库内附 pinhole_samples 与 ocam_samples 两套示例数据。

5.1 命令行参数与运行示例

程序要求 5 个参数(run_avm.cpp):

./bin/run_avm <image_path> <intrinsic_path> <extrinsic_path> <camera_model>

其中<camera_model>取值:0表示 OpenCV fisheye 模型,1表示 Ocam(Omnidirectional)模型,2表示 pinhole 模型。README 给出的三种运行方式:

# 直接运行(使用默认参数) cd ~./manual_calib/ ./bin/run_avm # pinhole 示例数据 ./bin/run_avm pinhole_samples/imgs pinhole_samples/intrinsic pinhole_samples/extrinsic 2 # Ocam 示例数据 ./bin/run_avm ocam_samples/imgs ocam_samples/intrinsic ocam_samples/extrinsic 1

注意两套示例数据对应的相机安装高度不同:代码中默认bev2ground=5.1(pinhole 样本),当camera_model==1时切换为 Ocam 样本的四个高度值(Front/Left/Back/Right 分别约 6.078/6.252/6.310/6.281 m,见 run_avm.cpp),更换数据时务必核对安装高度。

5.2 数据格式:JSON 内参与外参

程序通过 include/intrinsic_param.hpp 的LoadIntrinsic与 include/extrinsic_param.hpp 的LoadExtrinsic读取 JSON。内参文件要求形如 pinhole_samples/intrinsic/Front.json:顶层键为<sensor>-intrinsic,其param.cam_K.data为 3×3 矩阵、param.cam_dist.data为畸变系数行向量。外参文件形如 pinhole_samples/extrinsic/Front.json:顶层键为<sensor>-to-<target>-extrinsic,param.sensor_calib.data为 4×4 变换矩阵(此处为 ground/BEV 系到相机系的T_CG)。四台相机固定命名为Front/Left/Back/Right.json。

5.3 交互操作与参数微调

程序启动后以 Pangolin 窗口显示 BEV 投影结果,并提供控制面板与键盘两种微调方式:

  • 键盘微调:字符表{'q','a','w','s','e','d','r','f','t','g','y','h'}分别对应 roll/pitch/yaw/tx/ty/tz 六个自由度的正向与负向调整(ManualCalibration,见 run_avm.cpp),每按一键即对当前相机外参乘以对应的微调增量矩阵。
  • 面板微调:Pangolin 面板提供步长调节(deg step默认 0.3°,t step(cm)默认 6 cm,对应代码中cali_scale_degree_=0.3、cali_scale_trans_=0.06)、相机选择(frame0-3)、单相机微调按钮(± x/y/z degree、± x/y/z trans)、Reset(恢复初始外参)与 Save Image 按钮。
  • 拼接模式:stiching开关开启后,窗口显示四相机联合环视图,保存时会将四台相机结果一次性写入calibration_0.txt~calibration_3.txt(JSON 格式 4×4 矩阵,见saveResult)。

每次调整后程序都用当前外参重新执行project_on_ground并刷新画面,实现所见即所得的微调体验。完整操作流程可参照仓库 lidar2camera/README.md 中描述的手动标定交互规范。

六、核心原理小结与选型建议

从源码可以归纳出两套并行的技术路线:

无标定板自动标定(auto_calib / auto_calib_fisheye)

  • 依赖场景纹理而非标定板,适合道路场景快速部署;
  • 算法本质是基于公共视野光度一致性的外参优化:BEV 投影建立"地面像素 ↔ 相机像素"映射,纹理提取圈定可比较区域,随机搜索在 6 维外参空间最小化灰度差平方和;
  • 粗(±3° 分区间并行搜索)→ 精(±1°)→ 微调(±0.01°)三阶段搜索有效扩大收敛域;
  • 通过camera_model与data_set两个开关即可切换 pinhole/fisheye 与对应初始化参数。

标定板路线(auto_calib_target)+ 手动微调(manual_calib)

  • auto_calib_target 用 solvePnP 从 3D-2D 对应直接求解外参,流程确定、可重复,适合产线;
  • manual_calib 适合在自动结果基础上做人工精修,或在自动标定不可用的场景兜底;
  • 两者共用 pinhole/Ocam/fisheye 三种投影模型的选择逻辑,保证模型一致性。

选择建议:普通环视相机优先用 auto_calib,鱼眼环视相机用 auto_calib_fisheye(注意其内部已内置 fisheye 畸变初值与 1000×1000 BEV 配置);产线场景用 auto_calib_target 并自行替换 3D/2D 标定点;需要在自动结果上精修或无法自动标定时,用 manual_calib 按传感器模型选择对应示例数据作为模板。

引用

本文内容基于 surround-camera/README.md 及其四个子模块文档整理,算法细节与参数均取自对应源码。该模块对应的学术工作为论文Automatic Surround Camera Calibration Method in Road Scene for Self-driving Car(arXiv:2305.16840),若在研究中使用了本项目,可按仓库 README 中给出的 BibTeX 条目引用:

@misc{2305.16840, Author = {Jixiang Li and Jiahao Pi and Guohang Yan and Yikang Li}, Title = {Automatic Surround Camera Calibration Method in Road Scene for Self-driving Car}, Year = {2023}, Eprint = {arXiv:2305.16840}, }
  • 自动驾驶
  • 计算机视觉

【免费下载链接】SensorsCalibration

OpenCalib: A Multi-sensor Calibration Toolbox for Autonomous Driving

项目地址:https://gitcode.com/gh_mirrors/se/SensorsCalibration
点击查看免费下载

相关推荐

上一篇:APK-Installer:免模拟器免费 3 分钟跑起第一个 APK
下一篇:3步跑起2D几何光学仿真:Ray Optics 从本地部署到自定义模块开发的实操手册

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 7:03:58

Linux下LaTeX环境搭建:TeX Live安装配置与踩坑实战指南

TeX Live 是我在 Linux 上折腾得最久也受益最多的工具之一。以前在 Windows 上写论文&#xff0c;装个完整版 CTex 套装就算完事&#xff0c;但迁移到 Linux 之后才发现&#xff0c;发行版安装、路径配置、字体管理、编译链选择&#xff0c;每一步都有隐藏的坑。这篇内容就是把…

作者头像 李华
网站建设 2026/10/16 7:03:58

OpenSpec规范驱动开发:从需求歧义到可验证交付的工程实践

1. 为什么我彻底放弃了“直觉编程”做了十几年的开发&#xff0c;我发现一个挺扎心的事实&#xff1a;大部分项目烂掉&#xff0c;不是程序员技术不行&#xff0c;而是大家从一开始就不知道自己在做什么。我见过太多这类场面——需求文档写得很含糊&#xff0c;产品口头讲两句就…

作者头像 李华
网站建设 2026/10/16 7:02:59

MATLAB 64位调用REFPROP物性计算:开箱即用配置与避坑指南

简介&#xff1a;这份资源面向需要在MATLAB环境中调用REFPROP进行流体热力学与传输性质计算的工程师、科研人员及高年级学生&#xff0c;尤其适合64位Windows平台下从事制冷、热交换器设计或化工流程模拟的用户。压缩包共117个文件&#xff0c;约1.64MB&#xff0c;以105个fld流…

作者头像 李华
网站建设 2026/10/16 7:02:59

SAP销售订单计划行确认数量批量更新:V_V2与MASS实操指南

去年同期&#xff0c;我被一票计划订单搞得焦头烂额&#xff1a;三百多张销售订单&#xff0c;每张都带两三条计划行&#xff0c;确认数量和实际交付计划对不上。挨个用VA02打开改&#xff0c;眼睛先报废&#xff0c;效率也完全没法看。一开始我想用标准事务码MASS直接批量改&a…

作者头像 李华