多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

自动驾驶鱼眼相机模型全解析:UCM、KB、DS原理与实战标定

自动驾驶鱼眼相机模型全解析:UCM、KB、DS原理与实战标定 1. 项目概述为什么鱼眼相机是自动驾驶的“广角之眼”在自动驾驶的感知世界里摄像头是获取环境信息的核心传感器之一。我们常说的前视、环视摄像头尤其是用于360度环视泊车和近距离感知的摄像头绝大多数都是鱼眼相机。你可能会好奇为什么不用普通的针孔相机模型简单来说普通相机的视野太窄了。想象一下你要把车停进一个狭窄的车位需要看清紧贴车身的障碍物、路沿和车位线一个视野只有60-70度的普通摄像头根本不够用它的“余光”看不到车身侧下方的情况。而鱼眼相机通过特殊的光学设计能够实现180度甚至更大的视场角相当于给车装上了“广角镜”甚至“超广角镜”让车辆拥有了贴近地面的“全景视野”。然而鱼眼镜头在带来广阔视野的同时也引入了严重的图像畸变。原本笔直的车道线在图像边缘会弯曲成弧线这种畸变不符合我们熟悉的针孔相机成像几何。因此直接使用针孔模型来处理鱼眼图像是行不通的我们必须为它建立专属的“身份证”——也就是鱼眼相机投影模型。这个模型精确描述了三维空间点是如何通过鱼眼镜头投影到二维图像平面上的是后续所有感知任务如目标检测、语义分割、视觉定位的几何基础。如果模型标定不准就像戴了一副度数不对的眼镜看到的整个世界都是扭曲的测距、定位都会产生巨大误差。目前业界主流的鱼眼相机模型主要有三种等距投影模型、立体投影模型和正交投影模型。但在自动驾驶工程实践中我们通常使用它们的参数化形式即标题中提到的UCM、KB和DS模型。理解并掌握这些模型意味着你拿到了处理鱼眼图像的“钥匙”。本次分享我将从一个感知算法工程师的实战角度带你彻底吃透这三种模型的原理、联系、标定方法并附上可直接集成使用的C/Python代码。无论你是正在入门自动驾驶感知的新人还是希望深化多传感器标定理解的从业者这篇内容都能提供扎实的参考。2. 核心原理从理想模型到参数化实战模型要理解UCM、KB、DS我们不能直接从公式开始那样会陷入数学符号的迷雾。让我们先从最基础的几何与光学概念入手建立直观认知。2.1 鱼眼成像的几何本质如何将半球“压平”针孔相机模型可以理解为一种“透视投影”遵循相似三角形原理图像上的点坐标与三维点的角度呈正切tan关系。而鱼眼相机的设计目标是在有限的图像平面比如CMOS传感器上容纳尽可能大的视野。它的核心思想是让图像坐标不再与角度呈线性关系而是与入射光线角度的某种函数关系。我们可以用一个简单的类比假设有一个半球形的穹顶代表180度的视野鱼眼相机的任务就是把这个穹顶内壁上的图案映射到一张平铺在地上的方形地毯代表图像平面上。不同的映射规则就产生了不同的理想投影模型等距投影地毯上某点到中心的距离与穹顶上对应点的高度即入射角成正比。这是最直观的“按角度等分”的映射方式。立体投影映射关系稍微复杂一些相当于从穹顶的南极点向平面做投影。这种映射能更好地保持局部形状但计算涉及正切函数。正交投影地毯上的点是穹顶上对应点在平面上的垂直投影。这会导致边缘的信息被极度压缩。在学术界我们常用r f * θ等距、r 2f * tan(θ/2)立体、r f * sin(θ)正交来描述这种关系其中r是像点到图像中心的距离f是焦距θ是入射角。然而现实世界的鱼眼镜头由于光学设计的复杂性如多组镜片组合其成像规律 rarely 严格符合某一种理想模型。它往往是几种效应的混合并且存在装配误差。因此我们需要更强大、更灵活的参数化模型来拟合真实的镜头。2.2 UCM模型平衡精度与复杂度的首选UCM全称Unified Camera Model有时也被称为Mei模型源于其提出者。它之所以在自动驾驶领域特别是环视泊车系统中应用极其广泛是因为它在精度和计算复杂度之间取得了非常好的平衡。UCM的核心思想是将鱼眼相机视为一个遵循针孔模型的标准相机但前面加了一个特殊的“虚拟球面”。它的投影过程分为两步球面投影三维点首先被投影到一个以相机光心为球心的单位球面上。这个步骤统一了所有方向的点。通用针孔投影将球面上的点通过一个位于球面后的虚拟针孔相机模型投影到图像平面。这里引入了一个关键参数ξ它代表了球心到针孔平面的距离偏移。其投影公式可以简化为一个三维点P先被归一化到球面坐标然后经过一个包含ξ参数的变换最后用标准的内参矩阵K映射到像素坐标。反向的去畸变过程从图像像素反推入射方向也因为有明确的几何解释而相对直接。UCM模型的优势模型统一当参数ξ0时UCM模型完全退化为标准的针孔模型。这意味着一套代码可以兼容处理鱼眼和普通镜头简化了系统架构。良好的外推性模型基于几何推导即使对于训练标定板未覆盖的视野区域其预测也相对可靠。适合SfM与SLAM其可逆性和良好的数学性质非常适合于需要频繁进行3D-2D坐标变换的视觉里程计和建图任务。它的主要挑战在于对于某些畸变非常大的超广角鱼眼镜头如视场角超过190度UCM模型可能拟合能力不足在图像最边缘的区域残差会变大。2.3 KB模型用多项式“拿捏”复杂畸变KB模型全称Kannala-Brandt模型是另一种极为流行的鱼眼相机模型在学术论文和许多开源库如OpenCV的fisheye模块中常见。它的思路与UCM的几何化路径不同更偏向于用多项式直接拟合入射角θ与像点半径r之间的函数关系。KB模型认为像点径向距离r可以表示为入射角θ的一个奇次多项式函数r(θ) k1*θ k2*θ^3 k3*θ^5 k4*θ^7 ...同时它还考虑了切向畸变p1, p2以建模镜头组装不对齐带来的影响。KB模型的优势强大的拟合能力高阶多项式给了它非常强大的灵活性能够以很高的精度拟合各种奇形怪状的鱼眼畸变包括那些UCM模型难以处理的超广角镜头。标定直观标定过程直接优化多项式系数目标明确。开源支持好OpenCV提供了成熟的cv::fisheye::calibrate函数使用方便。它的劣势同样明显物理意义弱多项式系数缺乏清晰的几何解释更像一个“黑盒”拟合。这可能导致在视场外推时行为不可预测。可能过拟合如果多项式阶数选择过高可能会过度拟合标定板数据中的噪声反而影响泛化性能。数值稳定性高阶多项式在计算时需要注意数值范围防止溢出。2.4 DS模型面向最严苛场景的双球面模型DS模型全称Double Sphere Model是近年来为应对超大视场角鱼眼镜头如全景相机而提出的一种改进模型。你可以把它理解为UCM模型的“升级版”。UCM模型只有一个虚拟球面而DS模型引入了两个球面。它的成像过程是光线首先射向第一个球面然后折射或理解为投影到第二个球面最后再投影到图像平面。这个双球面结构增加了模型的自由度使其能够更精确地描述光线在复杂鱼眼镜头组中的真实路径。DS模型的特点精度更高对于视场角极大如220度的鱼眼镜头其标定精度通常优于UCM和KB模型。仍具几何意义虽然比UCM复杂但依然保有球面投影的几何解释优于纯粹的多项式拟合。计算量稍大由于涉及两次球面投影其正投影和反投影的计算比UCM略复杂。在自动驾驶中DS模型目前更多应用于一些对周边感知精度要求极高的研究项目或特定车型上。主流的量产环视系统由于视场角通常在190度以内且对实时性要求极高UCM模型仍然是性价比最高的选择。模型选择心法在实际项目中不要盲目追求最复杂的模型。对于大多数车载环视鱼眼视场角180-190度优先使用UCM模型。它精度足够速度快且与后续的视觉算法兼容性好。只有当发现UCM模型在图像边缘重投影误差明显偏大且确认不是标定板质量问题后才考虑尝试KB或DS模型。KB模型是“数据驱动”的强者DS模型是“几何精度”的追求者。3. 实战代码从标定到应用的完整工具链理论说得再多不如一行代码。接下来我将以最常用的UCM模型为例展示一个完整的工具链包含标定、验证和坐标变换的C/Python代码片段。这里假设你已经采集好了鱼眼镜头的标定板图像推荐使用OpenCV的棋盘格或AprilTag。3.1 标定数据准备与角点提取标定的第一步是获取高精度的2D-3D点对应关系。我们使用棋盘格。import cv2 import numpy as np import glob # 配置参数 chessboard_size (9, 6) # 棋盘格内角点数量宽高 square_size 0.025 # 棋盘格方格实际边长单位米 # 准备3D对象点 (0,0,0), (0.025,0,0), (0.05,0,0) .... objp np.zeros((chessboard_size[0]*chessboard_size[1], 3), np.float32) objp[:, :2] np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) objp * square_size # 存储所有图像的对象点和图像点 objpoints [] # 3D点 imgpoints [] # 2D点 images glob.glob(./calib_imgs/*.jpg) for fname in images: img cv2.imread(fname) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 查找角点 ret, corners cv2.findChessboardCorners(gray, chessboard_size, None) if ret: # 亚像素级角点精确化 criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners_refined cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria) objpoints.append(objp) imgpoints.append(corners_refined) # 可视化可选 cv2.drawChessboardCorners(img, chessboard_size, corners_refined, ret) cv2.imshow(Corners, img) cv2.waitKey(500) cv2.destroyAllWindows()3.2 使用OpenCV进行KB模型标定OpenCV原生支持KB模型标定我们可以从这里开始作为一个基准。# 假设 objpoints 和 imgpoints 已从上一节获得 image_size gray.shape[::-1] # (width, height) # 初始化内参和畸变系数 K_init np.eye(3) D_init np.zeros((4, 1)) # KB模型通常使用4个径向畸变系数(k1,k2,k3,k4) # 执行鱼眼标定 rms, K, D, rvecs, tvecs cv2.fisheye.calibrate( objpoints, imgpoints, image_size, K_init, D_init, flagscv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC cv2.fisheye.CALIB_CHECK_COND cv2.fisheye.CALIB_FIX_SKEW, criteria(cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6) ) print(f重投影误差 (RMS): {rms}) print(f内参矩阵 K:\n{K}) print(f畸变系数 D (k1, k2, k3, k4):\n{D.ravel()})3.3 实现UCM模型的正向投影与反向去畸变OpenCV没有直接提供UCM模型我们需要自己实现。以下是核心数学运算的Python代码。import numpy as np def project_ucm(point_3d, xi, K): 使用UCM模型将3D点相机坐标系投影到2D像素坐标。 Args: point_3d: (3,) 或 (N,3) numpy数组相机坐标系下的3D点。 xi: 标量UCM模型参数。 K: (3,3) 内参矩阵 [[fx, 0, cx], [0, fy, cy], [0, 0, 1]]。 Returns: pixel_coords: (2,) 或 (N,2) 像素坐标。 point_3d np.asarray(point_3d) if point_3d.ndim 1: point_3d point_3d.reshape(1, -1) # 1. 归一化到单位球面 norm np.linalg.norm(point_3d, axis1, keepdimsTrue) point_sphere point_3d / np.maximum(norm, 1e-12) # 2. UCM投影公式: z point_3d[2] xi * norm z point_3d[:, 2:3] xi * norm # 避免除零 z np.where(z 0, z, 1e-12) # 3. 投影到归一化平面 point_2d_normalized point_3d[:, :2] / z # 4. 应用内参矩阵 point_2d_homo np.hstack([point_2d_normalized, np.ones((point_2d_normalized.shape[0], 1))]) pixel_coords_homo (K point_2d_homo.T).T pixel_coords pixel_coords_homo[:, :2] / pixel_coords_homo[:, 2:3] return pixel_coords.squeeze() def undistort_ucm(pixel_coords, xi, K): 使用UCM模型将2D像素坐标反投影到单位球面方向去畸变。 Args: pixel_coords: (2,) 或 (N,2) numpy数组像素坐标。 xi: 标量UCM模型参数。 K: (3,3) 内参矩阵。 Returns: direction: (3,) 或 (N,3) 单位向量相机坐标系下的射线方向。 pixel_coords np.asarray(pixel_coords) if pixel_coords.ndim 1: pixel_coords pixel_coords.reshape(1, -1) # 1. 反投影到归一化平面 K_inv np.linalg.inv(K) pixel_homo np.hstack([pixel_coords, np.ones((pixel_coords.shape[0], 1))]) point_2d_normalized_homo (K_inv pixel_homo.T).T u, v point_2d_normalized_homo[:, 0], point_2d_normalized_homo[:, 1] # 2. 求解UCM反投影公式 # 根据公式: r_sq u^2 v^2, z (1 - xi^2 * r_sq) / (xi * sqrt(1-(2*xi-1)*r_sq) 1) r_sq u**2 v**2 sqrt_term np.sqrt(1 - (2*xi - 1) * r_sq) denominator xi * sqrt_term 1 z (1 - xi**2 * r_sq) / denominator # 3. 计算球面上的点 alpha xi z point_sphere np.column_stack([alpha * u, alpha * v, alpha * z - xi]) # 归一化得到方向向量 norm np.linalg.norm(point_sphere, axis1, keepdimsTrue) direction point_sphere / np.maximum(norm, 1e-12) return direction.squeeze() # 示例用法 if __name__ __main__: # 假设标定得到的内参和xi K np.array([[500, 0, 320], [0, 500, 240], [0, 0, 1]]) xi 0.8 # 典型的鱼眼镜头xi值在0.5~1.2之间 # 测试一个3D点 point_3d np.array([0.1, 0.2, 1.5]) # 相机前方1.5米处的一个点 pixel project_ucm(point_3d, xi, K) print(f3D点 {point_3d} 投影到像素坐标: {pixel}) # 测试去畸变 direction undistort_ucm(pixel, xi, K) print(f像素点 {pixel} 对应的单位方向向量: {direction}) # 验证该方向应与原始3D点方向一致只差一个尺度 original_direction point_3d / np.linalg.norm(point_3d) print(f原始3D点方向: {original_direction}) print(f方向误差: {np.linalg.norm(direction - original_direction)})3.4 标定UCM模型参数标定UCM模型就是通过优化找到最佳的K和xi。我们可以使用非线性最小二乘优化如Levenberg-Marquardt算法。from scipy.optimize import least_squares def residuals_ucm(params, objpoints, imgpoints): 计算UCM模型参数下的重投影误差。 params: 待优化参数 [fx, fy, cx, cy, xi] fx, fy, cx, cy, xi params K np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]]) error [] for objp, imgp in zip(objpoints, imgpoints): # 对于每一张标定板图片先估计外参旋转和平移 # 这里简化处理假设我们已经有了外参 rvec, tvec可通过PnP初步估计 # 实际标定中需要将外参也加入优化或分步求解 rvec, tvec estimate_pose_initial(objp, imgp, K, xi) # 需要实现一个初始位姿估计函数 R, _ cv2.Rodrigues(rvec) # 将世界坐标系下的3D点转换到相机坐标系 pts_3d_cam (R objp.T tvec).T # 投影到图像 pts_proj project_ucm(pts_3d_cam, xi, K) # 计算误差 error.append((pts_proj - imgp).ravel()) return np.concatenate(error) # 初始化参数可以从KB模型标定结果或经验值初始化 params_init [500, 500, 320, 240, 0.8] # [fx, fy, cx, cy, xi] # 执行优化此处为示意需要完整的objpoints, imgpoints数据 # result least_squares(residuals_ucm, params_init, args(objpoints, imgpoints), verbose2) # K_opt, xi_opt result.x[:4], result.x[4]标定实战要点标定板质量标定板必须平整角点检测要精准。AprilTag比传统棋盘格对光照和部分遮挡更鲁棒推荐使用。数据覆盖拍摄的标定板图像应尽可能覆盖整个图像区域特别是边缘和四个角。可以手持标定板在镜头前缓慢移动、旋转。初始值很重要优化UCM模型参数时给一个好的初始值能避免陷入局部最优。可以用OpenCV的鱼眼标定结果KB模型作为初始内参xi初始值设为0.8-1.0。评估指标不要只看最终的重投影误差RMS。一定要做可视化验证将去畸变后的图像与原始图像对比观察直线是否被拉直或者将标定板角点的重投影点用优化后的模型计算叠加到原图上观察偏差。4. 工程应用模型选型与性能优化指南在自动驾驶的嵌入式平台上算法的效率至关重要。鱼眼相机模型的处理速度直接影响感知模块的帧率。4.1 模型选型的量化考量我们可以从几个维度来量化比较三个模型特性维度UCM模型KB模型DS模型标定精度高对于FOV190°很高依赖多项式阶数最高尤其适合超大FOV外推稳定性好基于几何一般多项式可能震荡好基于几何计算复杂度低一次除法和若干加减乘除中需计算θ及高次幂中高两次球面投影内存占用低参数少Kξ中K径向/切向系数低参数略多于UCM与VSLAM兼容性优秀可逆雅可比易求良好良好OpenCV支持需自实现原生支持(fisheye)需自实现或第三方库选型结论对于量产项目UCM模型是默认首选。它的精度在环视常用视场角下完全达标且计算速度最快符合车规级芯片对效率的严苛要求。KB模型可以作为精度备份方案当UCM在某些镜头上表现不佳时启用。DS模型则用于前沿研究或对全景拼接精度有极端要求的场合。4.2 部署优化查表法与SIMD加速在车辆上实时处理鱼眼图像每次像素操作都调用undistort函数计算量太大。标准的优化方法是查表法。核心思想在初始化阶段预先计算好原图畸变图上每一个像素点(u_d, v_d)对应到去畸变后图像目标图上像素点(u_u, v_u)的映射关系存储为两个映射表MapX, MapY。实时处理时只需要一次高效的查表重映射操作cv::remap即可。// C 示例生成UCM模型去畸变映射表 cv::Mat generateUndistortMapUCM(const cv::Size image_size, const cv::Mat K, float xi) { cv::Mat map_x(image_size, CV_32FC1); cv::Mat map_y(image_size, CV_32FC1); float fx K.atdouble(0, 0); float fy K.atdouble(1, 1); float cx K.atdouble(0, 2); float cy K.atdouble(1, 2); for (int v 0; v image_size.height; v) { for (int u 0; u image_size.width; u) { // 1. 目标图像像素坐标 (u_u, v_u) - 归一化平面坐标 (x_u, y_u) float x_u (u - cx) / fx; float y_u (v - cy) / fy; // 2. UCM反投影归一化坐标 - 单位球面方向向量 float r_u_sq x_u * x_u y_u * y_u; float sqrt_term sqrt(1.0f - (2.0f*xi - 1.0f) * r_u_sq); float denominator xi * sqrt_term 1.0f; float z (1.0f - xi*xi * r_u_sq) / denominator; float alpha xi z; float x_d_norm alpha * x_u; float y_d_norm alpha * y_u; float z_d_norm alpha * z - xi; // 3. 将方向向量投影回畸变图像平面假设虚拟针孔模型 // 注意这里需要根据UCM的正向投影公式反推简化处理是假设一个虚拟焦距f1 // 更精确的做法是迭代求解或推导解析逆。此处为示意。 // 简化假设投影到另一个虚拟平面实际工程中此处是核心优化点。 // 我们这里用一个近似直接使用反投影后的归一化坐标映射回原图。 // (这是一个示意性代码真实实现需要完整的正反投影推导) float u_d x_d_norm * fx cx; float v_d y_d_norm * fy cy; map_x.atfloat(v, u) u_d; map_y.atfloat(v, u) u_d; } } // 实际中map_x和map_y需要存储的是从目标图到原图的对应位置用于remap。 // 此循环逻辑是计算“目标图某像素对应的原图像素坐标”。 return std::make_pair(map_x, map_y); } // 初始化时调用一次 auto [map_x, map_y] generateUndistortMapUCM(image_size, K, xi); // 实时处理每一帧 cv::Mat distorted_image capture_image(); cv::Mat undistorted_image; cv::remap(distorted_image, undistorted_image, map_x, map_y, cv::INTER_LINEAR);进一步优化生成映射表的双层循环是计算密集型任务可以使用多线程并行化。在ARM或x86平台可以利用NEON或AVX2指令集进行SIMD向量化计算进一步提升初始化速度。对于固定镜头的车载相机映射表只需计算一次并持久化存储启动时加载即可。4.3 与其他传感器的时间空间同步鱼眼相机模型标定完成后更重要的是与车上其他传感器如激光雷达、毫米波雷达、IMU进行联合标定即外参标定。空间同步外参标定目标是获取鱼眼相机与车体坐标系或其他传感器坐标系之间的旋转矩阵R和平移向量t。常用方法手工测量法精度低不推荐。基于联合标定板使用一个同时能被相机和激光雷达识别的标定板如带有棋盘格图案的立体靶标通过求解3D-3D或3D-2D的对应关系来标定。这是最主流的方法。自然特征法在车辆行驶过程中利用环境中的稳定特征点如车道线交点、标志牌角点进行在线标定与优化。时间同步自动驾驶中“感知-决策-控制”链路对时序要求极高。必须确保图像的时间戳、激光雷达点云的时间戳与车辆CAN总线信号的时间戳在同一个时间基准下通常是PTP或GPS时间。硬件触发是保证同步的最佳实践即由统一的时钟源同时给摄像头和激光雷达发送采集触发信号。5. 避坑指南与常见问题排查在实际开发和标定过程中你会遇到各种各样的问题。下面是我总结的一些典型“坑”及其解决方案。5.1 标定误差大的原因分析与解决问题现象可能原因排查步骤与解决方案重投影误差RMS 1个像素1. 标定板图像质量差模糊、过曝、欠曝。2. 角点检测不准。3. 标定板未覆盖全部视野特别是边缘。4. 镜头景深小部分图像失焦。1. 检查图像重新采集清晰、光照均匀的图像。2. 使用cv::cornerSubPix并调整窗口大小和迭代条件。尝试AprilTag。3. 确保标定板出现在图像上下左右及中心各个位置并有一定倾斜角度。4. 调整镜头焦距或使用小光圈增加景深。去畸变后图像中心区域扭曲内参中心(cx, cy)标定不准确。1. 检查标定板是否在图像中心区域有足够多的姿态。2. 在优化时尝试先固定cx, cy为图像中心优化其他参数后再放开。图像边缘直线仍为曲线1. 模型选择不当如用UCM拟合超广角。2. 标定板未覆盖图像最边缘区域。3. 镜头存在非径向畸变如切向畸变未建模。1. 尝试切换到KB模型增加高阶项或DS模型。2. 专门采集标定板紧贴图像边缘的图片。3. 在KB模型中启用切向畸变参数p1, p2进行标定。不同距离标定结果不一致镜头存在严重的场曲像差违反了单一投影模型的假设。1. 这是鱼眼镜头的物理限制。可在标定时让标定板距离与主要应用距离如泊车时的地面保持一致。2. 考虑使用更复杂的模型如多项式分区域建模但会极大增加复杂度。5.2 模型部署中的数值稳定性问题除零错误在UCM/DS模型的正反投影计算中分母可能接近零。编码时务必添加微小阈值如1e-12进行保护。开方负值在反投影公式中sqrt(1 - (2*xi-1)*r^2)可能因r过大对应视场外点或xi参数不合理而为负。需要做max(0, ...)处理并记录异常点。参数范围xi参数通常应大于0.5。优化时需对其设置合理边界如[0.3, 2.0]防止优化器跑到不合理的区域导致计算崩溃。5.3 与下游感知模块的衔接标定好的模型最终要用于鸟瞰图变换、目标检测、深度估计等任务。鸟瞰图变换这是环视泊车的核心。你需要知道每个鱼眼相机相对于地面的外参高度、俯仰角。通过undistort得到去畸变图像后再根据相机-地面的单应性矩阵进行IPM逆透视变换。关键点确保地面假设是平坦的并且外参准确否则生成的鸟瞰图拼接会有错位或拉伸。目标检测直接在鱼眼图像上训练检测网络可以让网络学习畸变不变性特征。但如果想用预训练的在普通图像上的模型一种做法是先进行去畸变但会损失边缘信息。另一种做法是在训练时对数据加载层增加一个在线“鱼眼畸变模拟”的数据增强让模型适应各种畸变。视觉定位在基于特征的VSLAM或视觉里程计中你需要使用相机模型将特征点反投影为单位向量用于后续的PnP或三角化。务必使用与你标定模型一致的投影/反投影函数混用模型是致命的错误。最后分享一个我个人的深刻体会鱼眼相机模型的标定三分靠算法七分靠数据。花时间采集一套覆盖全面、清晰、多姿态的标定板图像远比后期调参优化来得有效。在量产项目中我们甚至会为每个型号的镜头建立温度补偿表因为温度变化会导致镜头镜片发生微小的形变从而影响内参。自动驾驶无小事每一个细节的精度都关乎最终系统的安全与可靠。
返回列表