我有一台鱼眼镜头,我已经校准过了。我需要通过使用所述棋盘的单个图像,内部参数和棋盘格的大小来计算棋盘上的相机姿势。不幸的是,许多校准库首先从一组图像中计算外部参数,然后计算内部参数,这基本上是“反向”和“反向”。我想要的程序。当然,我可以将我的棋盘图像放在我用于校准的其他图像集中并再次运行校准程序,但它非常繁琐,而且,我不能使用不同的棋盘格用于内部校准的尺寸。任何人都可以指出我正确的方向吗?
编辑:在阅读了francesco的回答后,我意识到我没有通过校准相机来解释我的意思。我的问题始于我没有经典的内在参数矩阵(因此我无法实际使用Francesco描述的方法)。实际上我用Scaramuzza程序校准了鱼眼相机(https://sites.google.com/site/scarabotix/ocamcalib-toolbox),它基本上找到一个将3d世界点映射到像素坐标的多项式(或者,将像素反投影到单位球面的多项式)。现在,我认为这些信息足以找到相机姿势w.r.t.棋盘,但我不确定如何继续。答案 0 :(得分:0)
我认为通过"校准"你的意思是你的相机有针孔模型。
然后,您的棋盘平面和图像平面之间的转换是单应性,您可以使用通常的DLT算法从角落的图像估计。然后,您可以将其表达为内在参数A和[xyt]矩阵的乘积,其中x和y列是世界的x和y单位向量(即棋盘' s)坐标系,t是从摄像机中心到同一帧原点的矢量。那就是:
H =标度* A * [x | y | t]
因此
[x | y | t] = 1 / scale * inv(A)* H
选择比例使x和y具有单位长度。一旦你有x和y,第三个轴就是它们的叉积。
答案 1 :(得分:0)
solvePnP程序计算相机坐标中棋盘(CB)的外在姿势。 openCV在其3D重建模块中添加了一个fishEye库,以适应具有大视野的相机中的严重失真。当然,如果你的内在矩阵或变换不是经典的内在矩阵,你必须修改PnP:
现在你有了所谓的标准化相机,其中消除了内在的矩阵效应。
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 = [R 00 ,R 01 ,R 02 ,T x ,R 10 ,R 11 ,R 12 ,T y ,R 20 ,R2 1 ,R 22 ,T z ] T
和A,b 由已知的u,v,x,y,z - 像素和CB角坐标组成;
然后求解x = V的最后一列,其中A = ULV T ,并从x组装旋转和平移矩阵。然后,几乎没有“凌乱”的步骤,这些步骤实际上非常典型的这种处理:
一个。确保你有一个真正的旋转矩阵 - 在R2 = UV T 上执行正交Procrustes,其中R = ULV T
B中。计算比例因子scl = sum(R2(i,j)/ R(i,j))/ 9;
℃。更新转换矢量T2 = scl * T并检查Tz> 0;如果是负反转T并否定R;
现在,R2,T2为非线性算法优化提供了一个很好的起点,例如Levenberg Marquardt。这是必需的,因为先前的线性步骤仅优化参数的代数误差,而非线性步骤优化正确的度量,例如像素距离的平方误差。但是,如果您不想执行所有这些步骤,则可以利用openCV的fish-eye library。