相机外部标定

camera extrinsic calibration

我有一个鱼眼相机,我已经校准过了。我需要通过使用所述棋盘的单个图像、内在参数和棋盘正方形的大小来计算相机姿势 w.r.t 棋盘。不幸的是,许多校准库首先从一组图像中计算外部参数,然后计算内部参数,这本质上是我想要的 "inverse" 过程。当然,我可以将我的棋盘图像放在我用于校准的其他图像集合中,然后再次 运行 校准程序,但这非常乏味,而且,我不能使用不同尺寸的棋盘用于本征校准的那些。谁能指出我正确的方向?

编辑:阅读 francesco 的回答后,我意识到我没有通过校准相机来解释我的意思。我的问题始于我没有经典的内在参数矩阵(所以我实际上不能使用 Francesco 描述的方法)。事实上,我用 Scaramuzza 的程序校准了鱼眼相机 (https://sites.google.com/site/scarabotix/ocamcalib-toolbox),它基本上找到了一个将 3d 世界点映射到像素坐标的多项式(或者,将像素反向投影到单位球体的多项式)。现在,我认为这些信息足以找到相机位姿 w.r.t。棋盘,但我不确定具体如何进行。

我假设 "calibrated" 你的意思是你的相机有一个针孔模型。

那么你的棋盘平面和图像平面之间的变换是单应性的,你可以使用通常的 DLT 算法从角点的图像中估计出来。然后,您可以将其表示为内在参数矩阵 A 和 [x y t] 的乘积,其中 x 和 y 列是世界(即棋盘)坐标系的 x 和 y 单位向量,t 是从相机中心到同一帧原点的向量。即:

H = 比例 * A * [x|y|t]

因此

[x|y|t] = 1/比例 * inv(A) * H

选择比例,使 x 和 y 具有单位长度。一旦你有了 x 和 y,第三个轴就是它们的叉积。

solvePnP 过程计算相机坐标中棋盘 (CB) 的外部姿态。 openCV 在其 3D 重建模块中添加了一个 fishEye 库,以适应具有大视野的相机中的显着失真。当然,如果你的内在矩阵或变换不是经典的内在矩阵你必须修改 PnP:

  1. 撤消您所做的任何反向投影
  2. 现在你有了所谓的归一化相机,消除了内在矩阵效应。

    k*[u,v,1]T = R|T * [x, y, z, 1]T

解决这个问题的方法是先写出k的表达式:

k=R20*x+R21*y+R22*z+Tz

然后在

中使用上面的表达式
k*u = R00*x+R01*y+R02*z+Tx
k*v = R10*x+R11*y+R12*z+Tx

您可以重新排列项以获得 Ax=0,受制于 |x|=1,其中未知

x=[R00, R01, R02, Tx, R10, R11, R12, T y, R20, R21, R22 , Tz]T

和A,b 由已知的u, v, x, y, z - 像素和CB角坐标组成;

然后求解 x=V 的最后一列,其中 A=ULVT,以及来自 x 的 assemble 旋转和平移矩阵。然后有几个“乱七八糟”的步骤实际上对于这种处理非常典型:

一个。确保你有一个真正的旋转矩阵 - 在你的 R2 = UVT 上执行正交 Procrustes,其中 R=ULVT

乙。计算比例因子scl=sum(R2(i,j)/R(i,j))/9;

C。更新平移向量 T2=scl*T 并检查 Tz>0;如果是负反转 T 并取反 R;

现在,R2、T2 为 Levenberg Marquardt 等非线性算法优化提供了一个良好的起点。这是必需的,因为先前的线性步骤仅优化参数的代数误差,而非线性步骤优化正确的度量,例如像素距离的平方误差。但是,如果您不想执行所有这些步骤,您可以利用 openCV 的 fish-eye library