2. 鱼眼相机基础

鱼眼相机是环视泊车系统的“眼睛”。它用一枚焦距极短、视角极大的镜头,把车身周围约 180°~195° 的半球空间压缩到一张图像里。代价是:图像不再符合人眼熟悉的“直线仍是直线”的透视规律,而是出现强烈的桶形弯曲。要把它用于测距、拼接和与超声波融合,必须先弄清它“如何成像、如何畸变、如何用参数描述、如何标定”这条链路。

一、鱼眼镜头成像模型:从入射角到像素坐标

普通针孔模型假设“像高 = 焦距 × tan(入射角)”,当入射角接近 90° 时 tan 值趋于无穷,无法成像。鱼眼镜头改用“等距投影”等非线性映射,把大角度入射光“压”进有限像面。工程上最常用的是四类投影模型:

  • 等距投影(equidistant):r = f·θ,像高与入射角成正比,是多数车载鱼眼的首选,角度分辨率均匀。
  • 等立体角投影(equisolid angle):r = 2f·sin(θ/2),常用于需要均匀亮度分布的场景。
  • 正交投影(orthographic):r = f·sinθ,最大视角约 180°。
  • 体视投影(stereographic):r = 2f·tan(θ/2),保角性好但边缘拉伸大。

其中 θ 是入射光线与光轴的夹角,r 是像点到主点的距离。实际镜头不会严格符合某一模型,因此标定时通常用多项式 r(θ)=k₁θ+k₂θ³+k₃θ⁵+… 来拟合真实映射,这也是 OpenCV fisheye 模型的核心思想。

鱼眼成像模型:入射角 θ → 像高 r 的映射关系 光线入射与像面投影 光轴 鱼眼镜头 像面 θ r 不同投影模型的 r-θ 曲线 θ r 等距 fθ 正交 f·sinθ 体视 2f·tan(θ/2) 针孔 f·tanθ(发散) θ 增大时,鱼眼模型像高增长远慢于针孔模型,故能容纳超大视场

二、畸变类型:径向为主,切向为辅

鱼眼图像的畸变可分为两类。第一类是径向畸变,由镜头曲率造成,表现为桶形(负畸变):越靠近边缘,直线越向外弯。鱼眼镜头径向畸变极大,不能用普通针孔的 k₁、k₂ 小系数描述,必须用 θ 多项式或专用畸变表。第二类是切向畸变,由镜头与传感器不平行、装配偏心引起,量级小但会破坏对称性,标定时用 p₁、p₂ 修正。

在环视系统中,畸变不是“错误”,而是设计的一部分。我们不会把鱼眼图“拉直成针孔”,而是保留其大视场,通过标定得到映射表,把每个像素反投影到归一化球面或地面,再重投影到虚拟俯视图。因此畸变模型必须与后续拼接使用的模型一致,否则接缝处会出现错位和重影。

判断畸变方向的小技巧:把车停在有清晰直线的车位旁,观察画面边缘的停车线。若直线向外鼓出,是桶形畸变;若向内凹,是枕形畸变。鱼眼几乎总是桶形。

三、内参与外参:描述“怎么拍”和“在哪拍”

内参描述相机自身的成像几何,外参描述相机相对车体或地面的位姿。二者共同决定一个三维点如何落到像素上。

参数类别符号/示例物理含义标定输出
焦距fx, fy(像素)镜头焦距折算到像素尺度内参矩阵 K
主点cx, cy(像素)光轴与像面交点内参矩阵 K
鱼眼畸变k₁…k₄θ 多项式系数畸变向量 D
切向畸变p₁, p₂镜头与传感器不平行畸变向量 D
旋转R(3×3)相机相对车体坐标系的姿态外参矩阵 [R|t]
平移t(3×1,mm)相机光心在车体坐标系的位置外参矩阵 [R|t]

内参通常一次标定后长期使用,但受温度、振动、装配影响会缓慢漂移;外参则更容易变化,例如后视镜被碰、保险杠拆装、车辆载重改变导致车身俯仰变化。环视拼接对外参尤其敏感,几毫米的平移误差就会在接缝处放大成明显的错位。

四、标定原理与常见工具

标定的本质是:已知标定板上若干特征点的三维坐标,找到一组参数,使它们投影到图像后的位置与实际检测位置误差最小。这是一个非线性最小二乘问题,常用 Levenberg–Marquardt 迭代求解。

  1. 采集:在车辆四周布置标定布或标定板,覆盖每个相机的重叠区域和边缘视场。
  2. 检测:提取棋盘格角点、圆点中心或 ArUco 标记中心,得到像素坐标。
  3. 初值:用线性方法或厂商提供的标称值给出 K、D、R、t 的初始估计。
  4. 优化:最小化重投影误差,迭代更新参数。
  5. 验证:检查重投影误差(一般要求 < 0.5 像素)、拼接接缝和地面直线度。
# OpenCV 鱼眼标定核心流程(示意)
objp = np.zeros((6*9, 3), np.float32)
objp[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2) * square_size

ret, K, D, rvecs, tvecs = cv2.fisheye.calibrate(
    object_points, image_points, image_size, K, D,
    flags=cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC |
          cv2.fisheye.CALIB_FIX_SKEW)

# 去畸变 + 重映射
map1, map2 = cv2.fisheye.initUndistortRectifyMap(
    K, D, np.eye(3), K_new, image_size, cv2.CV_16SC2)
undistorted = cv2.remap(img, map1, map2, cv2.INTER_LINEAR)

常见工具包括:OpenCV fisheye 模块(开源、灵活)、MATLAB Camera Calibrator(交互友好、适合离线分析)、Kalibr(支持多相机联合标定,适合环视)、以及各家智驾平台自带的环视标定工具(如基于标定布的全自动流水线)。选择工具时重点看三点:是否支持鱼眼模型、是否支持多相机联合优化、是否能输出与下游拼接一致的参数格式。

常见误区:用普通针孔模型去标鱼眼镜头。结果是在画面中心误差尚可,边缘误差迅速增大,拼接后接缝处出现明显断裂。另一个误区是只标内参不标外参,或外参用卷尺粗略测量,导致俯视图比例失真、超声波与视觉目标对不上。

五、复盘:标定质量决定融合上限

在鱼眼环视与超声波融合泊车中,视觉负责提供丰富的纹理和语义,超声波负责近距精确测距。两者要在同一车体坐标系下对齐,前提就是鱼眼相机的内外参准确、畸变模型正确。标定不是一次性的“出厂动作”,而应纳入日常诊断:当拼接画面出现错位、超声波报警位置与图像目标偏移时,优先复查外参和标定板检测质量,而不是急于调整融合算法。把标定做扎实,后续的拼接、测距和融合才有可靠的地基。