相机标定及棋盘格标定法详解
什么是相机标定?
相机标定(Camera Calibration)是指通过一组已知空间几何结构的物体(如棋盘格)拍摄图像,计算出相机的内参矩阵和畸变系数的过程。
这一步使得我们能够从二维图像像素坐标恢复三维空间信息,或者进行精准的图像几何校正。标定结果通常包括:
相机内参矩阵 $K$
$$K = \begin{bmatrix} f_x & 0 & c_x \ 0 & f_y & c_y \ 0 & 0 & 1 \ \end{bmatrix}$$ 其中,$f_x, f_y$ 是水平和竖直方向上的焦距(像素单位),$c_x, c_y$ 是主点坐标。畸变系数 $D$
包含径向和切向畸变参数,如 $k_1, k_2, p_1, p_2, k_3$ 等。旋转和平移向量 用于描述相机坐标系与世界坐标系之间的位置关系。
相机标定是计算相机内外参的过程。通过标定,我们能获得:
- 内参(Intrinsic Parameters):相机的固有属性,如焦距$(f_x, f_y)$、光心位置$(c_x, c_y)$和畸变参数。
- 外参(Extrinsic Parameters):相机相对于世界坐标系的位置和朝向,即旋转矩阵$R$和平移向量$t$。
标定的目标是建立3D物体坐标与图像坐标之间的映射关系。
在计算机视觉中,标定后的相机矩阵$K$通常表示为:
$$K = \begin{bmatrix} f_x & 0 & c_x \ 0 & f_y & c_y \ 0 & 0 & 1 \ \end{bmatrix}$$
结合畸变参数,可以纠正成像中的径向和切向畸变。
棋盘格标定法
棋盘格标定法是工业界和学术界应用最为广泛的标定方式,因其角点容易定位且结构规则。
简介
棋盘格标定法利用具有已知几何形状的二维平面棋盘作为标定样板。其关键步骤包括:
准备棋盘格
典型棋盘由黑白相间的方格组成,角点(内角交点)作为标定点。在多张不同角度的棋盘图像中检测角点
使用OpenCV的findChessboardCorners()
函数自动定位棋盘格内角点。亚像素级角点精确化
通过cornerSubPix()
精细调整角点位置,提高标定精度。对应三维空间点与二维图像点
三维点多为棋盘格上预先定义的规则坐标,例如$(0,0,0),(1,0,0),\ldots$。调用
calibrateCamera()
计算相机内外参
通过最小化重投影误差的优化方法,求得相机参数。
核心步骤:
- 准备一个具有多个方格单元的棋盘格标定板,已知单元格大小(如 $20 \times 20$ 毫米)。
- 采集多张棋盘格在不同姿态的图像。
- 使用角点检测算法找到每张图像中棋盘格的角点(图像点)。
- 结合棋盘格的物理坐标(空间点),利用对应点进行相机参数求解。
数学模型
在针孔相机模型下,三维空间点 $P_w = (X_w, Y_w, Z_w)$ 通过变换到相机坐标系后投影到像素坐标 $p = (u, v)$:
$$s \begin{bmatrix} u \ v \ 1 \ \end{bmatrix} = K \begin{bmatrix} R & t \end{bmatrix} \begin{bmatrix} X_w \ Y_w \ Z_w \ 1 \ \end{bmatrix}$$
其中:
- $s$ 是尺度因子。
- $R$ 是旋转矩阵,$t$ 是平移向量。
- $K$ 是内参矩阵。
根据上述方程,给定一组标定点的空间坐标及其对应像素点,利用非线性优化(如Levenberg-Marquardt)求解 $K$、$R$、$t$ 和畸变参数。
投影模型
世界坐标系中的3D点$X_w = [X,Y,Z,1]^T$通过相机坐标变换和投影变为图像点$x = [u,v]^T$:
$$s \begin{bmatrix} u \ v \ 1 \end{bmatrix} = K [R \quad t] \begin{bmatrix} X \ Y \ Z \ 1 \end{bmatrix}$$
其中:
- $K$为相机内参矩阵
- $R$为3×3旋转矩阵
- $t$为3×1平移向量
- $s$为尺度因子
重投影误差
最小化目标是重投影误差:
$$\min_{K, R_i, t_i} \sum_{i=1}^N \sum_{j=1}^M | x_{ij} - \hat{x}_{ij} |^2$$
其中:
- $x_{ij}$为第$i$幅图中第$j$个检测到的角点
- $\hat{x}_{ij}$为第$i$幅图对应的3D点经过投影后的点
优化完成后,即得到相机的内外参数和畸变系数。
相机标定Python实现及说明
下面代码通过模块化和详细注释,提高代码的可读性和复用性。
|
|
小结:
- 相机标定是获取相机准确内外参数的基础,广泛应用于机器视觉、三维重建等领域。
- 棋盘格标定法因其简单直观、角点检测稳定,是最常用的标定方法。
- 通过多视角棋盘图像,检测角点,亚像素精细化,配合OpenCV的
calibrateCamera
函数完成相机参数估计。 - 最终通过重投影误差评估标定结果的准确性,误差越小越好。
- 优化代码结构可以提升易懂性与复用性,便于实际工业或科研项目中的应用。
姿态估计的Python代码优化与详解
|
|
代码详解和优化说明:
- 结构化设计
- 将标定数据加载封装成函数
load_calibration_data
便于复用和维护。 - 使用
main()
函数组织流程,清晰分离功能模块。 - 处理每张图像时,增加角点检测成功与否的判断,输出友好提示。
- 变量和参数说明
- chessboard_size 定义棋盘格内角点数目,和标定板物理结构一致。
- objp 是棋盘格角点的三维世界坐标(假定Z=0平面),匹配图像角点对应关系。
criteria
为亚像素角点优化的迭代终止条件,保证检测角点高精度。- cube_size 方便调整立方体尺寸。
- 绘制加强
- 绘制时区分底面、边柱和顶面,颜色更直观(绿色底面、蓝色柱子、红色顶面)。
- 线宽和填充颜色根据功能区分,提升视觉效果。
- 交互体验
- 支持手动查看每张图像
- 支持按
s
键保存图像,方便批量结果保存。
总结
本文介绍了相机标定的基本原理和基于棋盘格的经典标定方法,结合数学模型重点阐述了相机内参数与变换关系。
通过重写的姿态估计代码,提供了实际如何利用OpenCV接口进行姿态求解与3D物体投影的实践示例,代码更规范,注释及变量命名清晰,便于学习和扩展。