3. 相机内参标定基础:内参矩阵、畸变模型、HALCON内参标定算子简介
相机内参标定,说白了就是搞清楚镜头和传感器之间的「内在关系」。你想想看,我们拍到的图像是二维的,但真实世界是三维的。要从二维像素坐标反推三维空间信息,就必须知道相机内部是怎么「映射」的。
我个人习惯把内参标定比作「给相机做体检」。你得知道它的焦距是多少、光心偏不偏、镜头有没有畸变。这些参数不准确,后面的手眼标定就是空中楼阁。
3.1 内参矩阵:相机的心脏
内参矩阵(Intrinsic Matrix)是相机模型的核心。它描述了从三维相机坐标系到二维图像坐标系的投影关系。数学上,它是一个 3×3 的上三角矩阵:
⎡ fx 0 cx ⎤
⎢ 0 fy cy ⎥
⎣ 0 0 1 ⎦
其中:
- fx, fy:分别是 x 和 y 方向的焦距(以像素为单位)。理想情况下 fx = fy,但实际制造误差会导致两者略有差异。
- cx, cy:主点坐标,即光轴与成像平面的交点。理论上应该在图像正中心,但实际往往有偏移。
内参矩阵的作用很简单:给定一个三维点 (X, Y, Z),它在图像上的像素坐标 (u, v) 可以通过以下公式计算:
u = fx * (X / Z) + cx
v = fy * (Y / Z) + cy
嗯,这里要注意:这个公式假设镜头是完美的针孔模型。但现实中没有完美的镜头,所以我们需要引入畸变模型。
3.2 畸变模型:镜头的「真实面目」
镜头畸变是光学系统固有的缺陷。我刚开始做视觉时,总觉得畸变校正可有可无。直到有一次做高精度测量,发现边缘的物体位置偏差了 0.5 毫米……从那以后,我再也不敢忽略畸变了。
常见的畸变分为两类:
| 畸变类型 | 现象 | 数学模型 | 典型场景 |
|---|---|---|---|
| 径向畸变 | 直线变弯曲,越靠近边缘越明显 | k1, k2, k3(三阶多项式) | 广角镜头、鱼眼镜头 |
| 切向畸变 | 镜头与成像平面不平行导致的倾斜 | p1, p2(两个参数) | 镜头装配偏差、碰撞后 |
在 HALCON 中,畸变模型通常用 5 个参数表示:k1, k2, k3, p1, p2。其中 k1, k2 是主要的径向畸变参数,k3 用于高畸变镜头(比如鱼眼),p1, p2 是切向畸变参数。
3.3 HALCON 内参标定算子简介
HALCON 提供了一套完整的内参标定工具链。我个人最喜欢的是它的「一步到位」风格——你只需要提供标定板图像,它就能自动完成角点提取、参数求解和误差评估。
核心算子就三个:
- create_calib_data:创建标定数据模型。你需要指定标定对象类型(通常是标定板)和相机数量。
- set_calib_data_cam_param:设置相机初始参数。这里可以给一个初始猜测值,比如焦距设为图像宽度的一半,主点设为图像中心。
- calibrate_cameras:执行标定。这个算子会同时优化所有相机的内参和外参。
一个典型的标定流程如下:
* 创建标定数据模型
create_calib_data ('calibration_object', 'calplate', 1, CalibDataID)
* 设置相机初始参数(以 5 百万像素相机为例)
StartCamParam := ['area_scan_division', 0.008, 0, 0, 0, 0, 0, 2448, 2048]
set_calib_data_cam_param (CalibDataID, 0, [], StartCamParam)
* 设置标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, 'caltab_30mm.descr')
* 对每张标定板图像进行角点提取和位姿估计
for i := 1 to 20 by 1
read_image (Image, 'calib_images/' + i$'02d')
find_calib_object (Image, CalibDataID, 0, 0, i-1, [], [])
get_calib_data_observ_contours (Contours, CalibDataID, 'caltab', 0, 0, i-1)
endfor
* 执行标定
calibrate_cameras (CalibDataID, [])
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
StartCamParam 的格式是 ['area_scan_division', Kappa, FocalLength, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]。其中 Kappa 是畸变系数(对于 division 模型),FocalLength 是焦距(米),Sx, Sy 是像元尺寸(米/像素)。如果你不知道像元尺寸,可以查相机 datasheet,或者设为 0 让 HALCON 自动估计。
3.4 知识体系总览
为了让你更直观地理解内参标定的知识结构,我画了一张图:
3.5 标定质量评估
标定做完不等于万事大吉。我见过太多人标定完就直接用,结果测量精度一塌糊涂。怎么判断标定好不好?看两个指标:
- 重投影误差(Reprojection Error):把标定板上的三维点投影回图像,计算投影点与实际检测到的角点之间的像素距离。HALCON 的
calibrate_cameras会自动输出这个值。我个人习惯要求误差小于 0.1 像素,如果超过 0.3 像素,我会重新采集数据。 - 畸变校正效果:用标定得到的内参对一张图像做畸变校正,观察图像边缘的直线是否变直了。如果校正后的图像边缘还是弯的,说明标定有问题。
change_radial_distortion_cam_par 生成一张畸变校正后的图像,然后拿尺子在屏幕上量一下标定板格点的间距是否均匀。这个方法虽然土,但很有效。
好了,内参标定的基础就讲到这里。记住:内参矩阵是相机模型的骨架,畸变参数是修正镜头缺陷的补丁,HALCON 的算子则是帮你自动完成这一切的工具。这三者缺一不可。